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 }