`
hao3100590
  • 浏览: 128650 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

KMP算法解析

阅读更多

 

一.理论基础

1.什么是kmp算法

同BF算法一样,就是串的模式匹配算法。

前面已经学过,我想都应该明白BF算法,就是用一种最直观的方式进行模式匹配。

优点:非常容易理解,是我们常用的思维方式来编程;

缺点:效率比较低,在匹配不成功的时候,回朔做了许多无用功;

 

从而根据其缺点,KMP算法就在回朔的时候做了工作,减少其无用功,那么怎么去减少回朔的工作呢?

下面举例说明:

例如:

s = abababc

t = ababc

其匹配过程如下图:


从图中我们看到了具体的变换过程,就是在回朔的过程中做了许多工作,S的i不需要回朔到1,只需要T回朔就可以了,那么怎么知道T回朔到什么位置才好呢?而从上面的图中我们也会发现,其实回朔跟S串是没有关系的,i压根就没变,变的是T的j,故而需要回朔的是T--待匹配模式串,所有回朔的位置是由T串的特点决定的!!当然,就这是问题2,求next数组。

 

2.为什么要求next数组

什么是next数组,简而言之,就是当不匹配的时候,从当前j的位置需要回朔的位置k

如上面的图中,当j=4的时候,回朔的位置是2,故而next[4]=2,这就是next的价值所在:决定在位置j不匹配的时候,回退到位置next[j].

 

3.next如何求之理论基础

既然求next完全是T的事,那么我这里就不像那些书上那样从S去分析,直接切入正题从T分析!书上有时候说的反而有碍思维,要是完全照书,我就不写这些了!

首先实例分析:



 2。代码

 

#include <iostream>
using namespace std;

int strLen(const char *s){
	if(!s) throw "串不能为空!\n";
	int i=0;
	while(*s != '\0'){
		i++;
		s++;
	}
	return i;
}		

/**
	*求next数组值
	*求模式t的next值并存入next数组中
	*t :待求模式数组
	*n :模式数组长度
	*next:next数组
	*/
void getNext(const char* t, int n, int* next){
	int i=0, j=-1;
	next[0] = -1;
	while(i < n){
		//如果j==-1,则回退到了开始位置(只有当开始的时候j才为-1,only one,以后至少都是0)
		//如果相等,匹配,故而向前,此时i的next的值就是j,且存的是最大的j
		if(j == -1 || t[j] == t[i]){
			i++;
			j++;
			next[i]=j;
		}else{//如果不等或j为其他,则j回到next[j]位置继续匹配
			j = next[j];
		}
	}
}

//1.Brute-Force算法(BF算法)
//子串定位(p若属于s,返回串p在s中的位置,否则返回0)
int strIndex(const char* s, const char* p){
	if(!s || !p) throw "串不能为空!\n";
	int i=0, j=0, r = 1;
	int sl = strLen(s);
	int pl = strLen(p);
	if(sl < pl) throw "参数异常,串长度!\n";
	while(i<sl && j<pl){
		if(s[i] == p[j]){
			i++; j++;
		}else{//恢复开始的位置的下一个位置
			i = i-j+1;
			j = 0;
		}
	}
	if(j >= pl) r = i-pl+1;
	else r = -1;
	return r;
}		


//2.KMP算法
//具体的讲解,见博文
int strIndex_kmp(const char* s, const char* p){
	if(!s || !p) throw "串不能为空!\n";
	int i=0, j=0, r = 1;
	int sl = strLen(s);
	int pl = strLen(p);
	if(sl < pl) throw "参数异常,串长度!\n";
		
	//求next
	int *next = new int[pl];
	getNext(p, pl, next);
	cout<<"next数组:";
	for(int j=0; j<pl; j++){
			cout<<next[j]<<" ";	
	}	
	cout<<endl;
	
	while(i<sl && j<pl){
		if(j==-1 || s[i] == p[j]){
			i++; j++;
		}else{//恢复到next[j]
			j = next[j];
		}
	}
	if(j >= pl) r = i-pl+1;
	else r = -1;
	delete next;
	return r;
}

int main(){
	//char a[] = {'a','c','a','b','a','a','b','a','a','b','c','a','c','a','a','b','c','\0'};
	//char b[] = {'a','b','a','a','b','c','\0'};
	char a[] = {'a','b','a','b','a','b','c','\0'};
	char b[] = {'a','b','a','b','c','\0'};
	try{
		cout<<"BF算法:"<<strIndex(a ,b)<<endl;
		cout<<"KMP算法:"<<strIndex_kmp(a, b)<<endl;

	}catch(const char* s){	
		cout<<s<<endl;
	}
}
  • 大小: 29.4 KB
  • 大小: 53 KB
分享到:
评论

相关推荐

    数据结构教学中KMP算法解析.pdf

    #资源达人分享计划#

    kmp算法步骤解析.md

    kmp算法

    KMP算法精解

    KMP算法精解,由浅入深,层层递进,深度解析KMP算法的实现。

    十三个常用算法

    六、教你从头到尾彻底理解KMP 算法 七、遗传算法 透析GA 本质 八、再谈启发式搜索算法 九、图像特征提取与匹配之SIFT 算法 九(续)、sift 算法的编译与实现 九(再续)、教你一步一步用c 语言实现sift 算法、上九...

    十五个经典算法研究与总结、目录+索引(定稿版)

    六、教你初步了解KMP算法、updated (KMP算法系列三篇文章) 六(续)、从KMP算法一步一步谈到BM算法 六(三续)、KMP算法之总结篇(必懂KMP) 七、遗传算法 透析GA本质 八、再谈启发式搜索算法 九、图像特征提取...

    ACM算法模版大集合

    一大堆模版 自己可以下来参考 应该有200个以上吧 自己下来看看 ... KMP Trie结构 后缀树/后缀数组 LCA/RMQ 有限状态自动机理论 排序 选择/冒泡 快速排序 堆排序 归并排序(OK) 基数排序 拓扑排序 排序网络

    LINUX日常代码集锦

    LINUX日常代码集锦,dns 数据包解析,kmp 算法 c 语言实现

    蛮力法求背包问题

    蛮力法解决0/1背包问题(轻松理解) 另有文档详细解析 还顺带写了KMP算法

    lrucacheleetcode-leetcode:leetcode算法学习记录golang版

    经典题目解析&golang版代码 简单难度 中等难度 困难难度 算法专项 KMP 算法 动态规划: 887. 鸡蛋掉落 5. 最长回文子串 494. 目标和 322. 零钱兑换 279. 完全平方数 198. 打家劫舍 152. 乘积最大子序列 139. 单词拆分...

    考研-数据结构-殷人昆.zip

    4.2.3 KMP 算法的改进 99 习题 102 习题答案 103 5 章 数组、矩阵与广义表 113 知识点讲解 113 5.1 数组 113 5.2 矩阵的压缩存储 114 5.2.1 矩阵 114 5.2.2 特殊矩阵和稀疏矩阵 115 5.3 广义表 121 习题 122 习题...

    sensitive-word-filter:敏感词匹配

     底层的实现原理采取的是AC自动机算法,AC自动机是在KMP算法和字典树上演变出来的一种多模匹配的算法。时间复杂度只取决于待分析文本的长度,和敏感词的数量无关。  有兴趣的小伙伴可以阅读关于KMP 和 AC自动机相关...

    java8集合源码分析-Notes:笔记

    字符串KMP算法 BitSet解决数据重复和是否存在等问题 哈希算法 一致性哈希算法? 1.1.2 Java语法糖 string的hash算法 hash冲突的解决办法:拉链法 foreach循环的原理 volatile关键字的底层实现原理 泛型类 泛型接口 ...

    leetcode跳动问题-leetcode-js:leetcode问题的解决方案(在javascript中),每个问题的时间复杂度都超过90+

    实现KMP算法 问题 30 连接所有单词的子串 提高效率,现在使用 DFS 问题 35 搜索插入位置 搞清楚原理 问题 44 通配符匹配 实施自下而上的动态规划,目前超过 54%/20% 问题 45 跳跃游戏 II 实施,目前超过 14%/36% ...

Global site tag (gtag.js) - Google Analytics