BF算法
已知 S字符串 和 T字符串,长度分别为 N 和 M 。在 S字符串 中匹配 T字符串;
- 首先比较 S[0] 和 T[0]
- 相等的话,同时后移动一位继续比较直到在 S字符串 中匹配到 T字符串
- 不相等的话,则判断 T字符串匹配位置是否为开始位置:如果是则 S串向后移动一位与 T串开始比较。如果不是,则与 T串头部开始比较;
KMP算法
核心:避免不必要的回溯,问题规模有模式串决定,不是有目标决定。将字符串中‘\0’去掉,在串头加入一个元素计入串长度;
next数组:指导者模式匹配串下一步匹配位置;
构建next数组:next[j]处失配,则查看 T[1](前缀)到T[j-1](后缀)的(j-1)个字符,前缀和后缀最多能匹配 n 个字符,则 next[i]=n+1; 表示在 S[i] 和 T[j] 比较时不相同,下一次比较 S[i] 和 T[next[j]];例如:T[6]={5,s,s,s,s,b}; 在 T[5]=b 处失配,前有 4 个字符,3个前缀匹配到3个后缀,所以下一次与 T[4]=s 处匹配;
通过分析得:next数组一个位置的值是将模式串中这个下标前的全部元素作为S串,查找从前缀开始T串,T串的长度为n时,则这个失配位置对应的next数组值即为n+1;
1 #include <stdio.h> 2 3 void get_next(char *T,int *next){ 4 int j=0,i=1;// j:前缀下标;i:后缀下标 5 next[1]=0;//next[0]储放数据 6 while(i<=T[0]){//T[0]字符的ascll码为T串长度 7 if(j == 0 || T[i] == T[j]){ 8 i++; 9 j++; 10 if(T[i] != T[j]){//判断失配位置和下一步匹配位置的字符是否相同,相同时就直接再下一步 11 next[i] = j; 12 }else{ 13 next[i] = next[j]; 14 } 15 }else{ 16 j=next[j]; 17 } 18 } 19 /* 前缀是固定的,后缀是相对的; 20 * 整个过程循环中的 j 是从T[0]开始能匹配到的最后一个前缀; 21 * 当模式匹配串不匹配,得到下一步匹配的下标为0时,表示S串要向后移动匹配T串头部; 22 * 进入if后自加1,正好为后缀后一个位置的next数组赋值n+1; 23 * 进入else中时,相当于以T[1]到T[i]为S串,T[1]到T[j]为T串匹配失配; 24 */ 25 }
浙公网安备 33010602011771号