寻找字符串

kmp

 

    a b a b h j  j  h a b  a   b   c   a    b

i   0 1 2 3 4 5 6 7 8 9 10 11 12 13  14

    a b a b c

j   1 2 3 4 5

 

 

    a b a b h j  j  h a b  a   b   c   a    b

i   0 1 2 3 4 5 6 7 8 9 10 11 12 13  14

         a b a b c

j        0 1 2 3 4

i==4,j==4时不匹配,则改变j,j=next[j],

则此时比较的是    i==4,j==2;

代码:

//    kmp
//
//
//    a b a b h j  j  h a b  a   b   c   a    b
//
//i   0 1 2 3 4 5 6 7 8 9 10 11 12 13  14
//
//    a b a b c
//
//j   1 2 3 4 5
//
//
//
//    a b a b h j  j  h a b  a   b   c   a    b
//
//i   0 1 2 3 4 5 6 7 8 9 10 11 12 13  14
//
//         a b a b c
//
//j        0 1 2 3 4
//
//i==4,j==4时不匹配,则改变j,j=next[j],
//
//则此时比较的是    i==4,j==2;
//代码:

#include <stdio.h>  
#include<iostream>
using namespace std;
#include <string.h>  
int next[32] = {-999};  
//next 数组存的是以j结尾的字符串的前后缀 最长相同字符字符串的 数目 
void get_next(string str1)
{
	int i=-1,j=0;
	next[j]=i;
	while(j<str1.length() )
	{
		if(i!=-1&&str1[i]!=str1[j])
		{
				i=next[i];
		}
		else
		{
			next[++j]=++i;
		}
	}
}
int kmp(char *str1,char *str2)
{
    int i,j;
    i = j = 0;
    while(i < strlen(str1)&&j<strlen(str2))
    {
        while(j!=-1&&str1[i]!=str2[j])//当不匹配时,
        {
            j = next[j];
        }
        i++;
        j++;

    }
    if(j == strlen(str2))
        return i-j;
    return -1;
}
int kmp1(char *str1,char *str2)
{
	int i=0,j=0,ans=0;
    while (i<strlen(str1))
    {
        if (str1[i]==str2[j] || j==-1)
        {
            i++;
            j++;
        }
        else j=next[j];
        if (j==strlen(str2))//如果匹配成功,则视作这次匹配失败,返回到上一次。 
        {
            ans++;
            j=next[j-1];
            i--;
        }
    }
    return ans;
}
int main(void)  
{  
    char s[100] ;//短 
    char t[100] ; //长 
    cin>>s>>t;
    int pos = 0;  
    int index;   
  
    printf("================ KMP ==============\n");  
    get_next(s);  
  
    index = kmp(t, s);  
    printf("index = %d\n", index);  
     printf("index = %d\n", kmp1(t,s));  
    
}  




 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值