字符串与KMP
1. 学习next数组的构造,看了视频先用前缀表构造吧
示例数据:
源串 a a b a a b a a f
匹配 a a b a a f
Nt 0 1 0 1 2 0
循环过程 a a b a a b a a f
对应下标
0 j=0;j++;
1 j=1;j++;
2 j=2;j++
3 j=3;j++;
4 j=4;j++;
5 j=2;j++;
6 j=3;j++;
7 j=4;j++;
8 j=5;j++;
class Solution {
public:
void getNext(string needle,vector<int>& next) {
int j=0;
next[0]=0;
for(int i=1;i<needle.length();i++) {
while(j>0&&needle[i]!=needle[j]) {
j=next[j-1];
}
if(needle[i]==needle[j]) j++;
next[i]=j;
cout<<j<<" ";
}
// cout<<endl;
}
int strStr(string haystack, string needle) {
vector<int> next(needle.length());
getNext(needle,next);
int j=0;
int left=0;
// cout<<endl;
for(int i=0;i<haystack.length();i++) {
while(j>0&&haystack[i]!=needle[j]) {
j=next[j-1];
}
if(haystack[i]==needle[j]) j++;
if(j==needle.length()) return i-needle.length()+1;
}
return -1;
}
};
459.重复的字符串
想到了用前缀表,但是不知道具体怎么做,用将前缀表先写出来,看了看了规律,例如:
abcabcabcabc
000123456789
next[j]对应的是以s[j]结尾的最长相等前后缀。
下面的if条件我还没想明白是为什么可以这么做,代码随想录上是说:数组长度减去最长相同前后缀的长度相当于是第一个周期的长度,也就是一个周期的长度,如果这个周期可以被整除,就说明整个数组就是这个周期的循环。
class Solution {
public:
void getNext(string s,vector<int>& next) {
int j=0;
next[0]=0;
for(int i=1;i<s.length();i++) {
while(j>0&&s[i]!=s[j]) {
j=next[j-1];
}
if(s[i]==s[j]) j++;
next[i]=j;
}
}
bool repeatedSubstringPattern(string s) {
vector<int> next(s.length(),0);
getNext(s,next);
int len=next[s.length()-1];
getNext(s,next);
int j=s.length()-1;
// while(j>0&&next[j]!=0) j=next[]
if(next[j]!=0&&s.length()%(s.length()-next[j])==0) {
return true;
}
return false;
}
};