KMP算法

KMP算法是用来匹配字符串的 一个时间复杂度较BF算法 小的算法~

我的注释超详细哦~

 

#include <stdio.h>

int KMPp(char c);//
每次输入后,进行匹配,返回是否匹配成功 成功为1
void nextpp(char *p);//
输入子串后 计算KMP++算法的k
int znum,i,p,n1,n2; //
子串长度,循环变量,执行指针,n1n2记录匹配序列位置
char zhch,zch[1000],nextp[1000];//
主串临时变量,字串,k
    int main()
    {

        printf("
请输入模式串长度:\n");
        scanf("%d",&znum);
        if (znum<1000)
        {
        printf("
好的,现在请输入模式串:\n");
        scanf("%s",zch);
       // for (i=0;i<znum;i++)  scanf("%c",&zch[i]);
     //  printf("
不要鸟我 我是测试:%c\n",zch[1]);
            nextpp(zch);
            printf("
好的,现在请输入主串:\n");
            p,n1=0;
            while(1)
            {
            scanf("%c",&zhch);
            n1++;
            if(KMPp(zhch))
                {
                    printf("
匹配成功! 从第%d个字符到第%d个字符。",n2-1,n1-1);
                    break;
                }
            }
        }
        else printf("
我擦,你也太贪心了、、、");
        return 0;
    }



int KMPp(char c)
{
if (p==-1) {p=0;return 0;}//
比对失败则输入下一个字符
if (p==0) n2=n1;//
置序列位置
if (c==zch[p])//
如果当前值正确,考虑是否为序列尾
    {
        if (p!=znum-1) {p++;return 0;}//
比对成功 进入下一个字符
        else return 1;//
匹配成功!
    }
else {p=nextp[p];KMPp(zhch);} //
不正确则递归
}


void nextpp(char *p)    //
求最长前缀序列==后缀序列成立的长度 同时 如果zj=zk nj=nk 0
{
//memset(nextp,-1,znum);//
清空失败函数
int i,j,x,k,t;
nextp[0]=-1;
nextp[1]=0;
for (i=2;i<znum;i++) //i
指构建nextnp[i]
    {
        for (j=i-1;j>0;j--)//j
指前后缀序列的长度 j-1为最大长度
            {
                k=0;
                for (x=0;x<j;x++)    if (p[x]!=p[i+x-j]) {k++; break;}
                //
核心步骤 比对每一个前后缀序列是否相等 求出从后比到前 节约步骤
                if (k==0)   {nextp[i]=j;break;}
            }
    }
        printf("
失败函数为:");
        for (i=0;i<znum;i++) printf("%d ",nextp[i]);
        printf("\n");
}


/*// 
我会告诉你们  这下面这个函数是错的- -  每次扫描全部序列 而不是以前  但是可以输出正确的结果 原因未明
void nextpp(char *p)    //
求最长前缀序列==后缀序列成立的长度 同时 如果zj=zk nj=nk 0
{
//memset(nextp,-1,znum);//
清空失败函数
int i,j,k,x,t;
nextp[0]=-1;
nextp[1]=-1;
for (i=2;i<znum;i++) //i
指构建nextnp[i]
    {
    for (j=1;j<znum-1;j++)//j
指前后缀序列的最大长度
    {
        for (k=1;k<j;k++)//k
指前后缀序列现在检查的长度
        {
            for (x=0;x<k;x++)    {if (p[x]!=p[znum-k+x]) break; }//
对于每一长度 分别求0到(k-1)和znum-1znum-1-k是不是相等
            if (x==k-1&&k>t) t=k;//
如果全部相等 s=k,且每次取最大值

        }
    }
        if (p[i]==p[t]) nextp[i]=nextp[t];
        else nextp[i]=t;

    }
        printf("
失败函数为:");
        for (i=0;i<znum;i++) printf("%d ",nextp[i]);
        printf("\n");
}
*/

posted on 2013-11-28 18:51  (~ ̄▽ ̄)~*  阅读(206)  评论(0)    收藏  举报

导航