鱼C论坛

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

关于BF算法和KMP算法

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

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

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

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


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

//KMP算法
int KMPIndex(SqString s,SqString t)                        
{
        int next[MaxSize],i = 0,j = 0;
        GetNext(t,next);
        while(i < s.length && j < t.length)
        {
                if(j == -1 || s.data[i] == t.data[j])
                {
                        i++;
                        j++;                                          //i,j各增1
                }
                else j = next[j];                                 //i不变,j后退
        }
        if(j >= t.length)
                return(i - t.length);
        else
                return(-1);
}


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

//修正后的求nextval数组的算法如下:
void GetNextval(SqString t,int nextval[])
{
        int j = 0,k = -1;
        nextval[0] = -1;
        while(j < t.length)
        {
                if(k == -1 || t.data[j] == t.data[k])
                {
                        if(t.data[j]!=t.data[k])
                                nextval[j] = k;
                        else
                                nextval[j] = nextval[k];
                }
                else
                        k = nextval[k];
         }
}

//修正后的KMP算法如下:
int KMPIndex(SqString s,SqString t)
{
        int nextval[MaxSize],i = 0,j = 0;
        GetNextval(t,nextval);
        while(i < s.length && j < t.length)
        {
                if(j == -1 || s.data[i] == t.data[j])
                {
                        i++;
                        j++;
                }
                else
                        j = nextval[j];
        }
        if(j >= t.length)
                return(i - t.length);
        else
                return(-1);
}


评分

参与人数 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-11-23 21:18

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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