1967. 作为子字符串出现在单词中的字符串数目字符串模式匹配-kmp算法和kmp优化算法(双百代码)
给你一个字符串数组 patterns 和一个字符串 word ,统计 patterns 中有多少个字符串是 word 的子字符串。返回字符串数目。
子字符串 是字符串中的一个连续字符序列。
示例 1:
输入:patterns = [“a”,“abc”,“bc”,“d”], word = “abc”
输出:3
解释:
- “a” 是 “abc” 的子字符串。
- “abc” 是 “abc” 的子字符串。
- “bc” 是 “abc” 的子字符串。
- “d” 不是 “abc” 的子字符串。
patterns 中有 3 个字符串作为子字符串出现在 word 中。
示例 2:
输入:patterns = [“a”,“b”,“c”], word = “aaaaabbbbb”
输出:2
解释:
- “a” 是 “aaaaabbbbb” 的子字符串。
- “b” 是 “aaaaabbbbb” 的子字符串。
- “c” 不是 “aaaaabbbbb” 的字符串。
patterns 中有 2 个字符串作为子字符串出现在 word 中。
示例 3:
输入:patterns = [“a”,“a”,“a”], word = “ab”
输出:3
解释:patterns 中的每个字符串都作为子字符串出现在 word “ab” 中。
对于这个题目,很多人可能就会暴力,匹配,但是,暴力匹配终究不是好的办法,时间开销太大,这里给出kmp算法和mmp优化算法,感兴趣可以学习一下,这个算法非常帮,在考研和工作中都是十分常见的:
kmp算法:
bool kmp_pattern_match(char *s,char *word,int lenw){
int lens=strlen(s);
int next[lens];
int i=0,k=-1;
next[0]=-1;
while(i<lens-1){
if(k==-1||s[i]==s[k]){
k++;
i++;
next[i]=k;
}
else{
k=next[k];
}
}
int is=0,iword=0;
while(is<lens&&iword<lenw){
if(is==-1||s[is]==word[iword]){
is++;
iword++;
}
else{
is=next[is];
}
}
if(is==lens){
return true;
}
else{
return false;
}
}
int numOfStrings(char ** patterns, int patternsSize, char * word){
int count=0;
int lenw=strlen(word);
for(int i=0;i<patternsSize;i++){
if(kmp_pattern_match(patterns[i],word,lenw)){
count++;
}
}
return count;
}
kmp优化算法
bool kmp_pattern_match(char *s,char *word,int lenw){
int lens=strlen(s);
int next[lens];
int i=0,k=-1;
next[0]=-1;
while(i<lens-1){
if(k==-1||s[i]==s[k]){
k++;
i++;
if(s[i]==s[k]){
next[i]=next[k];
}
else{
next[i]=k;
}
}
else{
k=next[k];
}
}
int is=0,iword=0;
while(is<lens&&iword<lenw){
if(is==-1||s[is]==word[iword]){
is++;
iword++;
}
else{
is=next[is];
}
}
if(is==lens){
return true;
}
else{
return false;
}
}
int numOfStrings(char ** patterns, int patternsSize, char * word){
int count=0;
int lenw=strlen(word);
for(int i=0;i<patternsSize;i++){
if(kmp_pattern_match(patterns[i],word,lenw)){
count++;
}
}
return count;
}