KMP算法
特点:主串不回溯,算法关键在于如何在对当前文本和模式串检索过程中,若出现了不匹配的情况,如何充分利用已经匹配的部分
KMP 求next数组
- 初始化
- 前后缀相同的情况
- 前后缀不同的情况
- next数组
//采用KMP算法处理该题目
//获取next数组
void getNext(int* next, const string &s) {
int j = -1; //表示右移一位, 初始位置为-1
next[0] = j;
int n = s.size();
//注意从下标为1开始遍历
//next[i] 表示 i(包括i)之前最长相等的前后缀长度(其实就是j)
for (int i = 1; i < n; i++) {
// 当s[i]!=s[j+1]时候,说明当前后缀不匹配
while (j >= 0 && s[i] != s[j+1]) {
j = next[j];//模版串回溯
}
//如果前后缀匹配,则j++, i++已经在每次循环结尾处理
if (s[i] == s[j+1]) j++;
//next[i] 赋值
next[i] = j;
}
}
int strStr(string haystack, string needle) {
// vector<int> next(needle.size(), 0);
if (needle.size() == 0) return 0;
int next[needle.size()];
int n = haystack.size();
// 获取next数组
getNext(next, needle);
// 匹配主串模式串
int j = -1; //因为next数组里记录的起始位置为-1
for (int i=0; i < n; i++) {
while (j>=0 && haystack[i] != needle[j+1]) {
j = next[j];
}
//如果前后戳
if (haystack[i] == needle[j+1]) {
j++;
}
if (j == (needle.size()-1)) {
return (i-needle.size()+1);
}
}
return -1;
}
std::string::npos
是 std::string
类中的一个静态常量,通常用于表示字符串操作中的特殊值,表示在字符串中未找到匹配的位置。npos
是 size_t
类型的常量,其值在不同平台上可能有所不同,但通常是一个非常大的正整数。
在 std::string
的成员函数中,npos
用于表示一个无效或未找到的位置。例如,在 find()
函数的返回值中,如果没有找到匹配的子字符串或字符,就会返回 std::string::npos
。
bool repeatedSubstringPattern(string s) {
string t = s + s;
//掐头去尾
t.erase(t.begin());
t.erase(t.end()-1);
//查看字符串中是否还存在
if (t.find(s) != std::string::npos) return true;
return false;
}