全局匹配KMP算法
KMP算法是通过分析模式字符串,预先计算每个位置发生不匹配的时候,所需GOTO的下一个比较位置,整理出来一个next数组,然后在上面的算法中使用。
本全局匹配KMP算法针对串的堆式存储数据结构
- # define MAXSIZE 45 //固定next数组的长度
- # define OK 1
- # define ERROR 0
- typedef int Status; //返回状态
- //存放匹配字符串的位置
- int indexArray[MAXSIZE] = {0};
- //记录匹配字符串出现的次数
- int searchIndex = 0;
- //------------------串的堆分配存储表示
- typedef struct {
- char* ch; //指针域,指向存放串值的存储空间基址
- int length; // 整型域:存放串长
- } HString;
next函数值仅取决于模式串本身而和相匹配的主串无关,因此从分析器定义出发而用递推的方法求得next函数的值。
- /*
- 功能:获取next函数;
- */
- void get_next(HString* t,int* next)
- {
- int i = 1,j = 0;
- *(next+1) = 0;
- while(i<t->length)
- {
- if(j == 0 || *(t->ch+i-1) == *(t->ch+j-1))
- {
- i++;
- j++;
- *(next+i) = j;
- }
- else
- j = *(next+j);
- }
- }
匹配过程中产生“失配”时,指针i不变,指针j退回到next[j]所知识的位置上重新经行比较,并且当指针j退至0时,指针id和指针j需同时加1。即若主串中的第i个字符和模式中的第1个字符不等,应从主串中的第i+1个字符起重新匹配。
当所匹配记录相等的字符数大于或等于模式串长度时,记录当前位置,即匹配合适的位置,然后继续进行下一组的匹配。
获取next函数算法的时间复杂度为O(m),通常模式串的长度m比主要串的长度n小得多,因此,对整个匹配算法来说是值得的。
在一般情况下,仅有一次模式匹配的时间复杂度为O(m+n),因此全局模式匹配的时间复杂度与匹配成功次数相关。为O(m+n)*b(b次)。
KMP算法的最大特点就是指示主串的指针不需回溯,整个匹配过程中,对主串仅需从头至尾扫描一编。
- /*
- 功能:kmp算法 从pos开始,获取串s中所有匹配串t位置,存放在全局函数indexArray中
初始条件:t非空,且i<=pos<=s->length- */
- status Index_KMP(HString* s,HString* t,int pos)
- {
- //处理非法输入
- if(!t || pos>1 || pos> s->length)
return ERROR;- //清空
- for(int k =0;k<MAXSIZE;k++)
- {
- indexArray[k] = 0;
- }
- searchIndex = 0;
- //得到next数组
- int j,next[MAXSIZE] = {};
- get_next(s,next);
- if (pos < 0 || pos > s->length)
- exit(0);
- int sLength = s->length;
- int tLength = t->length;
- int i = pos-1;
- j = 0;
- while(i<= sLength && j<=tLength)
- {
- if(j == 0 ||*(s->ch + i) == *(t->ch + j))
- {
- ++i;
- ++j;
- if(j>= tLength)
- {
- indexArray[searchIndex] = i-tLength+1;
- searchIndex++;
- }
- }
- else{
- j = *(next+j);
- }
- }
return OK;- }
高亮显示区域应为if(j== tLength) 。如果写成大于等于,当主串最后位置出现匹配的字符串,即给下列测试代码中的S1赋值为abaabc时,程序给数值赋值后,i继续自增加,造成最后输出结果为1 9 17 25 26。因此,应将if(j>= tLength)改成if(j== tLength)
测试如下:
- HString S1;
- InitHString(&S1);
- AssigHString(&S1,"abaabc");
- HString S;
- InitHString(&S);
- AssigHString(&S,"abaabcd abaabcf abaabcj abaabck");
- Index_KMP(&S,&S1,1);
- printf("S1在S中的出现次数:%d\n",searchIndex );
- for(int i=0;i<searchIndex;i++)
- printf("%d ",indexArray[i]);
- printf("\n");
显示结果为:1 9 17 25
总结,细心调试,同时要增强代码的健壮性。
全局匹配KMP算法的更多相关文章
- 自己对kmp算法的理解,借由 28. 实现 strStr() 为例
做题思路 or 感想 : 就借由这道题来理解一下kmp算法吧 kmp算法的操作过程我觉得有句话很合适 :KMP 算法永不回退 目标字符串 的指针 i,不走回头路(不会重复扫描 目标字符串),而是借助 ...
- 字符串查找算法总结(暴力匹配、KMP 算法、Boyer-Moore 算法和 Sunday 算法)
字符串匹配是字符串的一种基本操作:给定一个长度为 M 的文本和一个长度为 N 的模式串,在文本中找到一个和该模式相符的子字符串,并返回该字字符串在文本中的位置. KMP 算法,全称是 Knuth-Mo ...
- KMP算法匹配原理以及C++实现
原创作品,转载请注明出处:点我 假设A表示目标字符串,A="abababaababacb",B表示匹配模式,B="ababacb" 用两个指针i和j分别表示,A ...
- 【转】字符串匹配的KMP算法:移动位数 = 已匹配 - 部分匹配值(共有长度)
计算机的基本任务之一. 举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串"ABCDABD"? 许多算 ...
- 串的匹配:朴素匹配&KMP算法
引言 字符串的模式匹配是一种经常使用的操作. 模式匹配(pattern matching),简单讲就是在文本(text,或者说母串str)中寻找一给定的模式(pattern).通常文本都非常大.而模式 ...
- 从暴力匹配到KMP算法
前言 现在有两个字符串:\(s1\)和\(s2\),现在要你输出\(s2\)在\(s1\)当中每一次出现的位置,你会怎么做? 暴力匹配算法 基本思路 用两个指针分别指向当前匹配到的位置,并对当前状态进 ...
- KMP算法——字符匹配
暴力匹配: 假设现在我们面临这样一个问题:有一个文本串S,和一个模式串P,现在要查找P在S中的位置,怎么查找呢? 如果用暴力匹配的思路,并假设现在文本串S匹配到 i 位置,模式串P匹配到 j 位置, ...
- KMP算法 (字符串的匹配)
视频参考 对于正常的字符串模式匹配,主串长度为m,子串为n,时间复杂度会到达O(m*n),而如果用KMP算法,复杂度将会减少线型时间O(m+n). 设主串为ptr="ababaaababaa ...
- 算法数据结构 | 只要30行代码,实现快速匹配字符串的KMP算法
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是算法数据结构专题的第29篇文章,我们来聊一个新的字符串匹配算法--KMP. KMP这个名字不是视频播放器,更不是看毛片,它其实是由Kn ...
随机推荐
- LNMP 参数调优 ( 无注释 )
简介: PHP FastCGI 优点 1.PHP 脚本运行速度更快.PHP 解释程序被载入内存而不用每次需要时从存储器读取,极大的提升了依靠脚本运行站点的性能. 2.需要使用的系统资源更少.由于服务器 ...
- $.getJSON() 回调函数没有执行的原因
$.getJSON() 方法使用 AJAX 的 HTTP GET 请求获取 JSON 数据. 语法 $.getJSON(url,data,success(data,status,xhr)) url必填 ...
- Invalid command 'Header', perhaps misspelled or defined by a module not included in the server configuration
在Apache的配置文件 httpd.conf 中开启 LoadModule headers_module modules/mod_headers.so 即可解决这个问题.
- Java的SSH网站
1.框架 strusts2 + Hibernate + spring 2.图片 图1-1 网站结构 图1-2 java代码结构 3.源代码 3.1 UserAction.java package co ...
- 如何查看Mysql服务器上的版本
select version(); 1,mysql 的守护进程是mysqld [root@localhost ~]# service mysqld start 启动 MySQL: [确定] 你可以看看 ...
- mybatis+oracle如何批量执行多条update
接口 public void setStatus(List<Columns> columnsList); mapping xmlmapping 中使用foreach,关于标签的使用,资料非 ...
- Solidity oraclize解析Json格式数据
solidity虽然不能解析json数据但是oraclize_query可以直接处理: pragma solidity ^; import "github.com/oraclize/ethe ...
- Luogu 2000 拯救世界
从胡小兔的博客那里过来的,简单记一下生成函数. 生成函数 数列$\{1, 1, 1, 1, \cdots\}$的生成函数是$f(x) = 1 + x + x^2 + x^3 + \cdots$,根据等 ...
- code1796 社交网络
输入描述 Input Description 输入文件中第一行有两个整数,n 和 m,表示社交网络中结点和无向边的数 目.在无向图中,我们将所有结点从 1 到 n 进行编号. 接下来 m 行,每行用三 ...
- 3.3.2线程安全的HashMap
代码:public class SysHashMao { private static Map<String,String> map= Collections.synchronizedMa ...