KMP算法(next数组方法)
KMP算法之前需要说一点串的问题:
串:
字符串:ASCII码为基本数据形成的一堆线性结构。
串是一个线性结构;它的存储形式:
typedef struct STRING {
CHARACTER *head;
int length;
};
朴素的串匹配算法:
设文本串text = "ababcabcacbab",模式串为patten = "abcac" 其匹配过程如下图所示。
黑色线条代表匹配位置,红色斜杠代表失配位置
算法说明:
一般匹配字符串时,我们从目标字符串text(假设长度为n)的第一个下标选取和patten长度(长度为m)一样的子字符串进行比较,如果一样,就返回开始处的下标值,不一样,选取text下一个下标,同样选取长度为n的字符串进行比较,直到str的末尾(实际比较时,下标移动到n-m)。在普通的匹配中,假如从文本串的第i个字符来开始于模式串匹配。当匹配到模式串的第j位发现失配,即text[i+j] != patten[j]的时候,我们又从文本串的第i+1个位置来重新开始匹配。尽管我们已经知道了好多字符其实根本就匹配不上,我们还是进行了这个过程,这个时候回溯的过程会非常耗费我们的时间。这样的时间复杂度是O(n*m)。
代码如下:
int search(const char*str,const char *subStr) {
int strlen = strlen(str);
int subStrlen = strlen(subStr);
int i;
int j;
for(i = ;i <= strlen - subStrlen;i++){
for(j = ;j < subStrlen;j++){
if(str[i + j] != subStr[j])
break;
}判断subStrlen是否比较完成
}
}
KMP算法:
而KMP算法的实质就是,当遇到text[i+j] != patten[j]的时候,但是我们知道模式串中的 0~j-1 位置上的字符已经于i ~ i+j-1位置上的字符是完全匹配的。就不再重新从text[i+1]开始匹配,而是根据next数组的下标找到patten的下标,从那个下标开始匹配。从而时间复杂度为O(m+n)。
例如模式串Patten = "abaabcac"。其next数组如图所示:
我们可以看到这次的匹配在蓝色的c失配了,而c的下标为5,他的next数组的下标为2。因此,下次的匹配不再是从text[1]开始,而是从text[2]开始,这样就省去了不必要的比较。
代码如下:
#include <stdio.h>
#include <malloc.h>
#include <string.h> #include "kmpmec.h" void getNext(const char *str, int *next);
int KMPSearch(const char *str, const char *subStr); int KMPSearch(const char *str, const char *subStr) {
int strLen = strlen(str);
int subLen = strlen(subStr);
int *next;
int i = ;
int j = ; if (strLen <= || subLen <= || strLen < subLen) {
return -;
}
next = (int *) calloc(sizeof(int), subLen);
if (subLen > ) {
getNext(subStr, next);
} while (strLen - i + next[j] >= subLen) {
while (subStr[j] != && str[i] == subStr[j]) {
i++;
j++;
}
if (subStr[j] == ) {
free(next);
return i - subLen;
} else if (j == ) {
i++;
j = ;
} else {
j = next[j];
}
} free(next);
return -;
} void getNext(const char *str, int *next) { //得到next数组
int i = ;
int j = ;
boolean flag; next[] = next[] = ; //next数组的前两个下标一定为零
for (i = ; str[i]; i++) {
for (flag = TRUE; flag;) {
if (str[i-] == str[j]) { //通过比较失配位置的前一个和前一个下标元素的比较,获取next数组的下标。
next[i] = ++j;
flag = FALSE;
} else if (j == ) {
next[i] = ;
flag = FALSE;
} else {
j = next[j];
}
}
}
} int main(void) {
char str[];
char subStr[];
int result; printf("请输入源字符串:");
gets(str);
printf("请输入子字符串:");
gets(subStr); result = KMPSearch(str, subStr);
if (result == -) {
printf("字符串[%s]不存在子串[%s]\n", str, subStr);
} else {
printf("子串[%s]第一次出现在字符串[%s]中的下标为%d\n", subStr, str, result);
} return ;
};
KMP算法(next数组方法)的更多相关文章
- 转载-KMP算法前缀数组优雅实现
转自:http://www.cnblogs.com/10jschen/archive/2012/08/21/2648451.html 我们在一个母字符串中查找一个子字符串有很多方法.KMP是一种最常见 ...
- 第4章学习小结_串(BF&KMP算法)、数组(三元组)
这一章学习之后,我想对串这个部分写一下我的总结体会. 串也有顺序和链式两种存储结构,但大多采用顺序存储结构比较方便.字符串定义可以用字符数组比如:char c[10];也可以用C++中定义一个字符串s ...
- KMP算法next数组求解
关于KMP算法,许多教材用的是递推式求解,虽然代码简洁,但是有些不好理解,这里我介绍一种迭代求next数组的方法 KMP算法关键部分就是滑动模式串,我们可以每次滑动一个单位,直到出现可能匹配的情况,此 ...
- 数据结构之KMP算法next数组
我们要找到一个短字符串(模式串)在另一个长字符串(原始串)中的起始位置,也就是模式匹配,最关键的是找到next数组.最简单的算法就是用双层循环来解决,但是这种算法效率低,kmp算法是针对模式串自身的特 ...
- KMP算法&next数组总结
http://www.cnblogs.com/yjiyjige/p/3263858.html KMP算法应该是每一本<数据结构>书都会讲的,算是知名度最高的算法之一了,但很可惜,我大二那年 ...
- KMP算法 Next数组详解
题面 题目描述 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 为了减少骗分的情况,接下来还要输出子串的前缀数组next.如果你不知道这是什么意思也不要问,去百 ...
- 【文文殿下】浅谈KMP算法next数组与循环节的关系
KMP算法 KMP算法是一种字符串匹配算法,他可以在O(n+m)的时间内求出一个模式串在另一个模式串下出现的次数. KMP算法是利用next数组进行自匹配,然后来进行匹配的. Next数组 Next数 ...
- KMP算法(推导方法及模板)
介绍 克努斯-莫里斯-普拉特算法Knuth-Morris-Pratt字符串查找算法(简称为KMP算法)可在一个主文本字符串S内查找一个词W的出现位置.此算法通过运用对这个词在不匹配时本身就包含足够的信 ...
- poj1961(kmp算法next数组应用)
题目链接:https://vjudge.net/problem/POJ-1961 题意:给定一个长为n的字符串(n<=1e6),对于下标i(2<=i<=n),如果子串s(1...i) ...
- POJ-2752(KMP算法+前缀数组的应用)
Seek the Name, Seek the Fame POJ-2752 本题使用的算法还是KMP 最主要的片段就是前缀数组pi的理解,这里要求解的纸盒pi[n-1]有关,但是还是需要使用一个循环来 ...
随机推荐
- js DOM常见事件
js事件命名为on+动词 1.onclick事件,点击鼠标时触发,ondbclick双击事件 <h1 onclick="this.innerHTML='点击后文本'"> ...
- Python2的一些问题及解决办法
1. 无法注释中文的解决办法 # -*- coding:utf8 -*- # 添加这一行就行了 from django.contrib import admin from myapp.models i ...
- Cookie&Session与自定义session
cookie与session的区别? cookie是保存在浏览器端的键值对 session是保存在服务器端的键值对 session依赖于cookie 摘自: http://bubkoo.com/201 ...
- 观实验室PPT演讲有感
outline 一定要有 说话的语速要慢,压制住紧张的心情 提前一天发布PPT dont` argue with audience, especially professor and teachers ...
- ODAC(V9.5.15) 学习笔记(十四)TCRBatchMove
名称 类型 说明 AbortOnKeyViol Boolean 在处理数据时,如果发生主键冲突或主键校验失败时,是否中断 AbortOnProblem Boolean 发生问题时是否中断 Change ...
- Bootstrap3基础 img-responsive 响应式图片
内容 参数 OS Windows 10 x64 browser Firefox 65.0.2 framework Bootstrap 3.3.7 editor ...
- Android系统更新防互刷功能实现与分析【转】
本文转载自:https://blog.csdn.net/huangyabin001/article/details/44465145 版权声明:本文为博主原创文章,未经博主允许不得转载. htt ...
- JPush Flutter Plugin(Futter推送-极光推送)
https://pub.flutter-io.cn/packages/jpush_flutter JPush's officially supported Flutter plugin (Androi ...
- Shiro源码分析
1.入口类:AbstractAuthenticator 用户输入的登录信息经过其authenticate方法: public final AuthenticationInfo authenticate ...
- vs 附加进程 iis进程显示