备战 ACM 竞赛:C++ 高效实现常见算法模板

在 ACM 国际大学生程序设计竞赛中,算法的高效实现是取得好成绩的关键。本文将详细介绍竞赛中常用的几类算法模板,包括字符串处理算法、图论算法、动态规划算法以及常用数据结构的实现,帮助参赛者在赛场上快速应用,提升解题效率。

字符串处理算法

字符串处理在 ACM 竞赛中出现频率极高,涉及模式匹配、字符串哈希、前缀后缀等多种操作。以下是几种核心算法的 C++ 实现。

KMP 算法

KMP 算法是解决字符串模式匹配问题的高效算法,其核心在于利用前缀函数(部分匹配表)避免不必要的字符比较。

 

#include <iostream>

#include <vector>

#include <string>

using namespace std;

vector<int> computeLPS(string pattern) {

int m = pattern.size();

vector<int> lps(m, 0);

int len = 0; // 长度为len的最长前缀也是后缀

for (int i = 1; i < m; ) {

if (pattern[i] == pattern[len]) {

len++;

lps[i] = len;

i++;

} else {

if (len != 0) {

len = lps[len - 1]; // 回溯

} else {

lps[i] = 0;

i++;

}

}

}

return lps;

}

vector<int> kmpSearch(string text, string pattern) {

vector<int> result;

int n = text.size();

int m = pattern.size();

if (m == 0) return result;

vector<int> lps = computeLPS(pattern);

int i = 0; // text的索引

int j = 0; // pattern的索引

while (i < n) {

if (pattern[j] == text[i]) {

i++;

j++;

}

if (j == m) {

result.push_back(i - j); // 记录匹配起始位置

j = lps[j - 1];

} else if (i < n && pattern[j] != text[i]) {

if (j != 0) {

j = lps[j - 1];

} else {

i++;

}

}

}

return result;

}

int main() {

string text = "ABABDABACDABABCABAB";

string pattern = "ABABCABAB";

vector<int> matches = kmpSearch(text, pattern);

for (int pos : matches) {

cout << "Pattern found at position " << pos << endl;

}

return 0;

}

在上述代码中,computeLPS 函数用于计算模式串的前缀函数数组,kmpSearch 函数则利用该数组进行高效的模式匹配。KMP 算法的时间复杂度为 O (n + m),其中 n 是文本串长度,m 是模式串长度,大大优于朴素匹配算法的 O (n*m)。

字符串哈希

字符串哈希通过将字符串映射为一个整数,实现快速的字符串比较和查询。常用的有单哈希和双哈希(降低冲突概率)。

 

#include <iostream>

#include <string>

#include <vector>

using namespace std;

typedef long long ll;

const int BASE = 911382629;

const int MOD = 1e18 + 3;

// 预处理幂次

vector<ll> powBase;

void precomputePower(int maxLen) {

powBase.resize(maxLen + 1);

powBase[0] = 1;

for (int i = 1; i <= maxLen; i++) {

powBase[i] = (powBase[i - 1] * BASE) % MOD;

}

}

// 计算字符串的哈希值

ll computeHash(const string &s) {

ll hash = 0;

for (char c : s) {

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值