1、暴力匹配算法BF
假设现在我们面临这样一个问题:有一个文本串S,和一个模式串P,现在要查找P在S中的位置,怎么查找呢?
如果用暴力匹配的思路,并假设现在文本串S匹配到 i 位置,模式串P匹配到 j 位置,则有:
- 如果当前字符匹配成功(即S[i] == P[j]),则i++,j++,继续匹配下一个字符;
- 如果失配(即S[i]! = P[j]),令i = i - (j - 1),j = 0。相当于每次匹配失败时,i 回溯,j 被置为0。
理清楚了暴力匹配算法的流程及内在的逻辑,咱们可以写出暴力匹配的代码,如下:
int ViolentMatch(char* s, char* p) { int sLen = strlen(s); int pLen = strlen(p); int i = 0; int j = 0; while (i < sLen && j < pLen) { if (s[i] == p[j]) { //①如果当前字符匹配成功(即S[i] == P[j]),则i++,j++ i++; j++; } else { //②如果失配(即S[i]! = P[j]),令i = i - (j - 1),j = 0 i = i - j + 1; j = 0; } } //匹配成功,返回模式串p在文本串s中的位置,否则返回-1 if (j == pLen) return i - j; else return -1; }
2、KMP算法
KMP算法引入了一个F数组(在很多文章中会称为next,但笔者更习惯用F,这更方便表达),F[i]表示的是前i的字符组成的这个子串最长的相同前缀后缀的长度!
怎么理解呢?
例如字符串aababaaba的相同前缀后缀有a和aaba,那么其中最长的就是aaba。
1.本文中,所有的字符串从0开始编号
2.本文中,F数组(即其他文章中的next),F[i]表示0~i的字符串的最长相同前缀后缀的长度。
模板:
s是模式串,t是主串
//next[i]表示和模式串第i位匹配失败时,再去和模式串第next[i]位匹配 #include<iostream> #include<cstring> #include<cstdio> using namespace std; char s[100005],t[1000005]; int tot,nxt[1000005]; void kmp_pre(){ int i,j; int len=strlen(s); j=nxt[0]=-1;i=0; while(i<len){ while(j!=-1 && s[i]!=s[j]) j=nxt[j]; nxt[++i]=++j; } } void kmp(){ int i,j,ans; int m=strlen(s); int n=strlen(t); i=j=ans=0; while(i<n){ while(j!=-1 && t[i]!=s[j]) j=nxt[j]; ++i,++j;//这个是在匹配的时候 if(j==m){ ans++;//ans是有几个匹配的。 j=nxt[j]; } } printf("%d\n",ans); } int main(){ int tt; scanf("%d",&tt); while(tt--){ memset(nxt,0,sizeof nxt); scanf("%s%s",s,t); kmp_pre(); kmp(); } }
https://blog.csdn.net/f1033774377/article/details/82556438 一个能看的懂得教程
来源:https://www.cnblogs.com/h694879357/p/12293564.html