鱼C论坛

 找回密码
 立即注册
查看: 6653|回复: 7

关于BF算法和KMP算法

[复制链接]
发表于 2015-10-24 20:09:47 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
这两个算法可是弄了我好久的,终于搞明白了,出此贴温习下


  1. //Brute-Force算法
  2. int index(SqString s,SqString t)                    //目标串s,模式串t
  3. {
  4.         int i = 0,j = 0;                                                                //指针下标i标志s串,指针下标j标志t串
  5.         while(i < s.length && j < t.length)             //当各自指针下标小于各自的串的长度时,则执行该循环体
  6.         {
  7.                 if(s.data[i] == t.data[j])                  //如相等则继续匹配下一个字符
  8.                 {
  9.                         i++;                                    //主串和子串依次匹配下一个字符
  10.                         j++;
  11.                 }
  12.                 else                                        //如果不相等主串、子串指针回溯重新开始下一次匹配
  13.                 {
  14.                         i = i - j + 1;                          //主串从下一个位置开始匹配
  15.                         j = 0;                                  //子串从头开始匹配
  16.                 }
  17.         }
  18.         if(j >= t.length)
  19.                 return(i - t.length);                       //返回匹配的第一个字符的下标
  20.         else
  21.                 return(-1);                                 //模式匹配不成,返回-1
  22. }
  23. //总结:这个算法简单,易于理解,但效率不高,主要原因是:主串指针i在若干个字符序列比较相等后,若有一个字符比较不相等,仍需回溯(即i = i - j + 1)
  24. //该算法在最好的情况下的时间复杂度为O(m),即主串的前m个字符等于模式串的m个字符。在最坏的情况下的时间复杂度为O(nm)

  25. //KMP算法
  26. int KMPIndex(SqString s,SqString t)                        
  27. {
  28.         int next[MaxSize],i = 0,j = 0;
  29.         GetNext(t,next);
  30.         while(i < s.length && j < t.length)
  31.         {
  32.                 if(j == -1 || s.data[i] == t.data[j])
  33.                 {
  34.                         i++;
  35.                         j++;                                          //i,j各增1
  36.                 }
  37.                 else j = next[j];                                 //i不变,j后退
  38.         }
  39.         if(j >= t.length)
  40.                 return(i - t.length);
  41.         else
  42.                 return(-1);
  43. }


  44. //求next[]的值
  45. void GetNext(SqString t.int next[])                         //对模式串t,求next[]值
  46. {
  47.         int j,k;
  48.         j = 0;k = -1;next[0] = -1;
  49.         while(j < t.length - 1)
  50.         {
  51.                 if(k == -1 || t.data[j] == t.data[k])              //k为-1或比较的字符相等时
  52.                 {
  53.                         j++;k++;                                    
  54.                         next[j] = k;
  55.                 }
  56.                 else k = next[k];
  57.         }
  58. }
  59. //说明:上述定义的next[]在某些情况下仍有缺陷,例如,设主串s为"aaabaaaab",模式串t为"aaaab"

  60. //修正后的求nextval数组的算法如下:
  61. void GetNextval(SqString t,int nextval[])
  62. {
  63.         int j = 0,k = -1;
  64.         nextval[0] = -1;
  65.         while(j < t.length)
  66.         {
  67.                 if(k == -1 || t.data[j] == t.data[k])
  68.                 {
  69.                         if(t.data[j]!=t.data[k])
  70.                                 nextval[j] = k;
  71.                         else
  72.                                 nextval[j] = nextval[k];
  73.                 }
  74.                 else
  75.                         k = nextval[k];
  76.         }
  77. }

  78. //修正后的KMP算法如下:
  79. int KMPIndex(SqString s,SqString t)
  80. {
  81.         int nextval[MaxSize],i = 0,j = 0;
  82.         GetNextval(t,nextval);
  83.         while(i < s.length && j < t.length)
  84.         {
  85.                 if(j == -1 || s.data[i] == t.data[j])
  86.                 {
  87.                         i++;
  88.                         j++;
  89.                 }
  90.                 else
  91.                         j = nextval[j];
  92.         }
  93.         if(j >= t.length)
  94.                 return(i - t.length);
  95.         else
  96.                 return(-1);
  97. }

复制代码



评分

参与人数 1荣誉 +5 鱼币 +5 贡献 +5 收起 理由
~风介~ + 5 + 5 + 5 感谢楼主无私奉献!

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2015-10-26 14:02:15 | 显示全部楼层
之前学过, 现在忘记光光了~~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-10-30 09:53:49 | 显示全部楼层
支持楼主!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-11-5 15:58:20 | 显示全部楼层
本帖最后由 qunianjinri 于 2015-11-5 16:14 编辑

修正后的GetNextval 函数wile循环里少了个 j++ ,k++.另外t.length-1
     while(j < t.length - 1)
        {
                if(k == -1 || t.data[j] == t.data[k])
                {
                        j++;
                        k++;

                        if(t.data[j]!=t.data[k])
                                nextval[j] = k;
                        else
                                nextval[j] = nextval[k];
                }
                else
                        k = nextval[k];
        }
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-11-24 17:14:30 | 显示全部楼层
感谢分享
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-11-30 13:01:15 | 显示全部楼层

就是来顶 支持
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-12-1 08:55:37 | 显示全部楼层
就是来顶 支持:lol:
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-4-24 16:17:02 | 显示全部楼层
本帖最后由 磨牙耗子 于 2018-4-24 20:51 编辑

程序可以正常运行,还有点地方可能没有考虑到得,大手子指点下

#include<stdio.h>      
                                                 //为什么没有用strlen函数的有文件#include<string.h>也可以实现。
int main()
{
        char str[]="fishcshe.com",str2[50];
        int i,count,j,blag,m,n;
        printf("请输入要查找的字符串str2[]: ");
        gets(str2);
        m=strlen(str);
        n=strlen(str2);
        for(i=0;i < m;i++)         //用for循环会出现当子串第一次查找完成后会继续遍历查找后面的字符串,1.会增加运算量;2.但是
        {                                   //可以规避当主串中重复出现子串的现象,并以最后一个出现的子串的首字符位置作为输出位置。
                count=0;         
                for(j=        0;j<n;j++)
                {
                        if(str[i+j]==str2[j])
                        {
                                count++;
                                if(count==n)
                                {
                                        blag=  i;
                                        break;
                                }
                        }
                        else
                                break;
                }                       
        }
        if(blag>0)
       
                        printf("子串在主串第%d位存在\n",blag+1);
        else
                printf("子串不在主串中\n");
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-20 00:38

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表