IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C语言版KMP算法 -> 正文阅读

[C++知识库]C语言版KMP算法

对朴素匹配模式算法的改进:

主串指针不回溯只有模式串指针回溯

我们来讲解如何实现求next数组的代码

//求next数组
void getNext(SString S,int *next){
	next[1] = 0;
	int i = 1,j = 0;
	while(i<S.length){
		if(j==0||S.ch[i]==S.ch[j]){
			next[++i] = ++j;
		}else{
			j = next[j];
		}
	}
}

kmp我给他起了另一个名字,叫做看门牌

求next数组,next数组的含义,是字符串的前后缀交集最长的长度加1.

我们需要观察出两点,第一点,比如next[6] = 4,那么next[7]最大只能为5,也就是next[6]+1。

第二点至关重要

如 果 P n e x t [ j ] ≠ P j , 那 么 n e x t [ j + 1 ] 可 能 的 次 大 值 为 n e x t [ n e x t [ j ] ] + 1 如果P_{next[j]} ≠ P_j ,那么next[j+1]可能的次大值为next[next[j]]+1 Pnext[j]??=Pj?next[j+1]next[next[j]]+1

我们求出next数组的关键就是根据此

递归求出next数组值

接下来是kmp的代码

//kmp代码
int KMP(SString S,SString T){
	int i=1,j=1;
	int next[T.length+1];
	getNext(T,next);
	while(i<=S.length&&j<=T.length){
		if(j==0||S.ch[i]==T.ch[j]){
			++i;
			++j;
		}else{
			j = next[j];
		}
	}
	if(j>T.length){
		return i-T.length;
	}else{
		return 0;
	}
}

开始判断 S.ch[i]==T.ch[j] ,如果相等 ,那么继续比较后续字符,如果不相等,模式串进行回溯,当跳出循环,即已经匹配完所有字符,如果j已经大于T的长度时说明成功,反之失败

完整代码

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#define MAXLEN 255

typedef struct{
	char ch[MAXLEN];
	int length;
}SString;

//输入字符串
void assign(SString *S){
	int i = 1;
	char x;
	scanf("%c",&x);
	while(x!='\n'){
		S->ch[i++] = x;
		scanf("%c",&x);
	}
	S->length = i-1;
}
//打印字符串
void print(SString S){
	for(int i=1;i<=S.length;i++){
		printf("%c",S.ch[i]);
	}
	printf("\n");
}
//求next数组
void getNext(SString S,int *next){
	next[1] = 0;
	int i = 1,j = 0;
	while(i<S.length){
		if(j==0||S.ch[i]==S.ch[j]){
			next[++i] = ++j;
		}else{
			j = next[j];
		}
	}
}
//kmp代码
int KMP(SString S,SString T){
	int i=1,j=1;
	int next[T.length+1];
	getNext(T,next);
	while(i<=S.length&&j<=T.length){
		if(j==0||S.ch[i]==T.ch[j]){
			++i;
			++j;
		}else{
			j = next[j];
		}
	}
	if(j>T.length){
		return i-T.length;
	}else{
		return 0;
	}
}
int main(){
	SString S,T;
	printf("请输入主串:\n");
	assign(&S);
	printf("请输入模式串:\n");
	assign(&T);
	printf("匹配到的位置:%d",KMP(S,T));
	return 0;
}

测试

成功在这里插入图片描述
失败
在这里插入图片描述

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-09 18:05:39  更:2022-04-09 18:06:04 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 0:28:34-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码