KMP算法代码模板,c语言实现,附有题目

网上有很多kmp算法的博客,看了好久都没有弄懂,于是就自己写一篇。
首先我们需要明确几个定义:
前缀:字符串前面的一段
后缀:字符串后面的一段

kmp算法思想:寻找一个字符串的,前缀与后缀的最大匹配,该前缀后缀不能为它自身。
在朴素字符串匹配中,若某一点不匹配,则需要从头开始,这中间会做了有很多不必要的工作。
我们找到已匹配字符串段的后缀的最大前缀匹配,再将该前缀作为已匹配字符串往后遍历。
由于找到的是后缀的最大前缀匹配,因此可以保证不会有遗漏。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define maxn 1002000
#define maxm 1002000
int next[maxm];
void findnext(char s[]) {//寻找当前的后缀的最大的前缀匹配 
	int lens = strlen(s), i = 1, k = 0;//i=0时无匹配 
	while (i != lens) {
		if (s[i] == s[k])next[i] = k + 1, ++k, ++i;//若匹配,则最大匹配长度为k+1 
		else if (s[i] != s[k]) {//不匹配 
			if (k == 0)i++;//说明不存在 
			else k = next[k - 1];//回退,已匹配的字符串的最大前缀和后缀的匹配 
		}

	}
}
int main() {
	char s1[maxn], s2[maxm];
	int i, j, k, lens1, lens2;
	scanf("%s", s1);
	scanf("%s", s2);
	findnext(s2);
	lens1 = strlen(s1), lens2 = strlen(s2);
	for (i = 0, j = 0; i < lens1; i++) {//字符串匹配,输出所有匹配位置 
		if (s1[i] == s2[j]) {
			if (j == lens2 - 1) {//匹配了后再次寻找最大前缀 
				printf("%d\n", i - j + 1);
				j = next[j];
			}
			else	j++;
		}
		else {//不匹配 
			if (j == 0)continue;
			else j = next[j - 1], i--;
		}



	}

	for (i = 0; i < lens2; i++)printf("%d ", next[i]);


}

学完了自己也试试题目吧
P3375 【模板】KMP字符串匹配

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值