【数据结构】KMP算法代码实现(c语言、c++完整代码)

        本次程序的实现我分别用C语言和c++语言实现了一遍。

        在写代码之前先说一些前置知识,kmp算法的核心我认为是求next数组的值。求next数组的值必须知道下面的这段公式,总的来说next数组的求取是根据下面的公式进行编写的。至于公式是怎么推导出来的,各种数据结构的书籍已经写的很详细了我就不叙述了。

         关于怎么理解next数组的求取,其他博主写的也非常清楚了,我也不多说了。求取next的数组必须知道前缀、和后缀的概念,同时我感觉求取next数组有一点动态规划的影子。

注意:此次实现是从下标为0 的地方开始进行比较的,所以需要对公式修改,使其减一。

C语言版:        

#include <stdio.h>
#include <string.h>
void get_next(char s[],int next[]);
int KMP(char s1[],char s2[],int next[]);
int main() {
	int i= 0;
	int next[1000];
	char s2[] = "ce";
	char s1[] = "ababce";
	get_next(s2,next);
    
	i=KMP(s1,s2,next);
    printf("%d\n",i);
    return 0;
}
void get_next(char s[],int next[])
{	
	int len=0;
    int i=0;//后缀 
    int j=-1;//前缀 
    next[0]=-1;//第一位符前面没有前缀,由公式知设为-1. 
    len=strlen(s);
    while(i<len)  
    {
        if(j==-1||s[i]==s[j])
        {
            i++;
            j++;
			next[i]=j;
        }
        else
        {
            j=next[j];
        }
    }
}
int KMP(char s1[],char s2[],int next[])
{
    int i=-1;
    int j=-1;
    int len1=strlen(s1);
    int len2=strlen(s2);
    while(i<len1&&j<len2)
    {
        if(j==-1||s1[i]==s2[j])
        {
            i++;
            j++;
        }
        else
        {
            j=next[j];
        }
    }
    if(j>=len2)
        return i-len2+1;
    else
        return 0;
}


C++版:

#include<iostream>
#define MAXSIZE 100
using namespace std;
typedef struct {
	char ch[MAXSIZE];
	int length;
}SString;
//本次程序是从下标为0开始进行比较的,所以next数组的边界需要进行改变 。 
get_next(SString t,int next[]) {
	int i = 0;
	next[0] = -1;
	int j = -1;
	while(i < t.length) {
		if(j == -1||t.ch[i] == t.ch[j]) {
			i++;
			j++;
			next[i] = j;
		} else {
			j = next[j];
		}
	}
}
int kmp(SString s, SString t , int pos,int next[]) {
	int i = -1,j = -1;
	while(i < s.length && j < t.length) {
		if(j == -1|| s.ch[i] == t.ch[j]) {
			i++;
			j++;
		}
		else {
			j = next[j];
		}
	}
	if(j >= t.length) return i-t.length+1;
	else return -1;
}
int main() {
	int pos = 0;
	SString s,t;
	int next[100];
	cout<<"请输入字符主串:";
	cin>>s.ch;
	cout<<"\n请输入主串的长度:";
	cin>>s.length;
	cout<<"\n请输入子串:";
	cin>>t.ch;
	cout<<"\n请输入子串的长度:";
	cin>>t.length;
	get_next(t,next);
	cout<<"子串在主串中的起始位置为:";
	cout<<kmp(s,t,pos,next);
	return 0;
}

经过测试代码运行是正常的。

  • 12
    点赞
  • 57
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值