C语言实现KMP模式匹配算法


next:
/*!
* Description:
* author scictor <scictor@gmail.com>
* date 2018/7/4
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// https://tekmarathon.com/2013/05/14/algorithm-to-find-substring-in-a-string-kmp-algorithm/
/*What is Partial Match Table?
It is an array of size (pattern_length+1) where, for each position of i in pattern p, b[i] is defined such that it takes the ‘length of the longest proper suffix of P[1…i-1]’ that matches with the ‘prefix of P’.
What is longest prefix/suffix match??? Proper prefix is a prefix which is not same as the substring. Recall proper set which is a subset of a set but is not same as the set.
Why a prefix should match suffix of the pattern? its because when we shift the pattern its the prefix of P which comes towards the suffix. And also the key idea is that if we have successfully matched prefix P[1…i-1] of the pattern with the substring T[j-(i-1)…j-1] of the input string and P(i)!=T(j), then we dont need to reprocess any of the suffix T[j-(i-1)…j-1] since we know this portion of the text string is the prefix of the pattern that we have just matched.
*/
//"ababacb"
/**
* Pre processes the pattern array based on proper prefixes and proper
* suffixes at every position of the array
*
* @param ptrn
* word that is to be searched in the search string
* @return partial match table which indicates
*/
void kmp_next(const char *pattern, int patternLen, int *next) {
int i = , j = -; next[i] = j; // default next[0] = -1
while (i < patternLen) {
while (j >= && pattern[i] != pattern[j]) {
// if there is mismatch consider the next widest border
// The borders to be examined are obtained in decreasing order from
// the values b[i], b[b[i]] etc.
j = next[j];
}
i++;
j++;
next[i] = j;
}
for(int index = ; index < patternLen; ++index) printf("%d ", next[index]);
return;
} /**
* Based on the pre processed array, search for the pattern in the text
*
* @param text
* text over which search happens
* @param ptrn
* pattern that is to be searched
*/ //int matchIndex[128] = {0}; int kmp_search(const char *text, int textLen, const char *pattern, int patternLen) {
int i = , j = ; // initialize new array and preprocess the pattern
int next[patternLen + ];
memset(next, 0x00, sizeof(next)); // int idx = 0;
// memset(matchIndex, 0x00, sizeof(matchIndex)); kmp_next(pattern, patternLen, next); while (i < textLen) {
while (j >= && text[i] != pattern[j]) {
j = next[j];
}
i++;
j++; // a match is found
// if (j == patternLen) {
// printf("found substring at index:" + (i - patternLen));
// j = next[j];
// }
if (j == patternLen) {
printf("found substring at index:%d", (i - patternLen));
//j = next[j];
//matchIndex[idx++] = i - patternLen;
return (i - patternLen);
}
} // for(int k = 0; k < idx; ++k)
// {
// printf("%d ", matchIndex[k]);
// }
return -;
} /*
Index 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
Text(T) a b c a b d a b c a b d a b c a b d a b d a b c
Pattern(P) a b c a b d a b c
PMT (next[i]) -1 0 0 0 1 2 0 1 2 3
*/
// 4ms
int kmp(const char *text, int textLen, const char *pattern, int patternLen)
{
int *T;
int i, j; if (pattern[] == '\0')
return ; // Construct the lookup table
T = (int*) malloc( (patternLen + ) * sizeof(int) );
T[] = -;
for (i=; pattern[i] != '\0'; i++) {
T[i+] = T[i] + ;
while (T[i+] > && pattern[i] != pattern[T[i+]-])
T[i+] = T[T[i+]-] + ;
} for(int k = ; k < patternLen; ++k) printf("%d ", T[k]); // Perform the search
for (i=j=; text[i] != '\0'; ) {
if (j < || text[i] == pattern[j]) {
++i, ++j;
if (pattern[j] == '\0') {
return (i-j);
}
}
else j = T[j];
} free(T);
return -;
} /*const char *kmp_search(const char *text, const char *pattern)
{
int *T;
int i, j;
const char *result = NULL; if (pattern[0] == '\0')
return text; // Construct the lookup table
T = (int*) malloc((strlen(pattern)+1) * sizeof(int) );
T[0] = -1;
for (i=0; pattern[i] != '\0'; i++) {
T[i+1] = T[i] + 1;
while (T[i+1] > 0 && pattern[i] != pattern[T[i+1]-1])
T[i+1] = T[T[i+1]-1] + 1;
} // Perform the search
for (i=j=0; text[i] != '\0'; ) {
if (j < 0 || text[i] == pattern[j]) {
++i, ++j;
if (pattern[j] == '\0') {
result = text+i-j;
break;
}
}
else j = T[j];
} free(T);
return result;
}
*/
nextval:
void preKmp(char *x, int m, int kmpNext[]) {
int i, j;
i = ;
j = kmpNext[] = -;
while (i < m) {
while (j > - && x[i] != x[j])
j = kmpNext[j];
i++;
j++;
if (x[i] == x[j])
kmpNext[i] = kmpNext[j];
else
kmpNext[i] = j;
}
}
// text:y, len: n, match parttern:x, len: m
int KMP(char *y, int n, char *x, int m) {
int i, j, kmpNext[m];
/* Preprocessing */
preKmp(x, m, kmpNext);
/* Searching */
i = j = ;
while (j < n) {
while (i > - && x[i] != y[j])
i = kmpNext[i];
i++;
j++;
// if (i >= m) {
// printf("j-i=%d\n",j - i);
// i = kmpNext[i];
// }
if (i == m) {
//printf("j-i=%d\n",j - i);
return j - i;
//i = kmpNext[i];
}
}
return -;
}
int strStr(char* haystack, char* needle) {
int needleLen = strlen(needle);
if(needleLen == ) return ;
int hayLen = strlen(haystack);
if(hayLen == ) return -;
return KMP(haystack, hayLen, needle, needleLen);
}
C语言实现KMP模式匹配算法的更多相关文章
- [从今天开始修炼数据结构]串、KMP模式匹配算法
[从今天开始修炼数据结构]基本概念 [从今天开始修炼数据结构]线性表及其实现以及实现有Itertor的ArrayList和LinkedList [从今天开始修炼数据结构]栈.斐波那契数列.逆波兰四则运 ...
- KMP模式匹配算法
KMP模式匹配算法 相信很多人对于这个还有点不了解,或者说是不懂,下面,通过一道题,来解决软考中的这个问题! 正题: aaabaaa,其next函数值为多少? 对于这个问题,我们应该怎么做呢? 1.整 ...
- 线性表-串:KMP模式匹配算法
一.简单模式匹配算法(略,逐字符比较即可) 二.KMP模式匹配算法 next数组:j为字符序号,从1开始. (1)当j=1时,next=0: (2)当存在前缀=后缀情况,next=相同字符数+1: ( ...
- C++编程练习(7)----“KMP模式匹配算法“字符串匹配
子串在主串中的定位操作通常称做串的模式匹配. KMP模式匹配算法实现: /* Index_KMP.h头文件 */ #include<string> #include<sstream& ...
- 详细解读KMP模式匹配算法
转载请注明出处:http://blog.csdn.net/fightlei/article/details/52712461 首先我们需要了解什么是模式匹配? 子串定位运算又称为模式匹配(Patter ...
- 字符串的模式匹配算法——KMP模式匹配算法
朴素的模式匹配算法(C++) 朴素的模式匹配算法,暴力,容易理解 #include<iostream> using namespace std; int main() { string m ...
- 串、KMP模式匹配算法
串是由0个或者多个字符组成的有限序列,又名叫字符串. 串的比较: 串的比较是通过组成串的字符之间的编码来进行的,而字符的编码指的是字符在对应字符集中的序号. 计算机中常用的ASCII编码,由8位二进制 ...
- 浅谈KMP模式匹配算法
普通的模式匹配算法(BF算法) 子串的定位操作通常称为模式匹配算法 假设有一个需求,需要我们从串"a b a b c a b c a c b a b"中,寻找内容为"a ...
- 数据结构(三)串---KMP模式匹配算法
(一)定义 由于BF模式匹配算法的低效(有太多不必要的回溯和匹配),于是某三个前辈发表了一个模式匹配算法,可以大大避免重复遍历的情况,称之为克努特-莫里斯-普拉特算法,简称KMP算法 (二)KMP算法 ...
随机推荐
- Coolest Ski Route-不定起点和终点----在有向变的情况下---求最长路
这题最开始给你了N个点,M条边,边是单向边,问不指定起点和终点,最长路是什么??? 脑补一下,不定起点和终点的最短路,用弗洛伊德算法搞一搞,但是...那个垃圾算法的复杂度是N^3的,但是这个算法的M高 ...
- 百度之星-day1-1003-度度熊剪纸条
度度熊剪纸条 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Subm ...
- Visual Studio2015安装过程以及单元测试
安装环境: 安装版本: Visual Studio2015 安装过程: 因为我是在第一次老师安排的作业的时候感觉VC++6.0不如VS方便所以才装的Visual Studio2015,又安装了点插件, ...
- Atcoder C - Vacation ( DP )
C - Vacation Time Limit: 2 sec / Memory Limit: 1024 MB Score : 100100 points Problem Statement Taro' ...
- Flask-论坛开发-1-基础知识
对Flask感兴趣的,可以看下这个视频教程:http://study.163.com/course/courseLearn.htm?courseId=1004091002 1. 第一个 flask 程 ...
- activiti engine.schema.update DB_SCHEMA_UPDATE_FALSE
engine.properties # engine propertiesengine.schema.update=trueengine.activate.jobexecutor=falseengin ...
- back to top 回到顶部按钮 css+js
效果 html <p id="back-to-top"><a href="#top"><span></span> ...
- angular生命周期
概述 angular的组件及指令都有相应的声明周期: 创建, 更新, 销毁, 我们可以通过实现相应的生命周期钩子接口来进入相应的该声明周期的关键时刻 组件生命周期顺序 ngOnChanges: 当组件 ...
- Ajax 新建对象
XMLHttpRequest对象是Ajax的基础,用于后台与服务器进行数据交互. 新的浏览器支撑XMLHttpRequest,而旧的浏览器不支持. var vari; if(window.XMLHtt ...
- Jenkins中使用GitLab的配置
1. 概述 在Jenkins中从GitLab上拉取代码进行打包或测试. 2. 安装 Jenkins和GitLab默认已经安装好,安装过程此处不再赘述. 在Jenkins上安装Git和Gitlab插件, ...