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算法 ...
随机推荐
- B. Equations of Mathematical Magic
思路 打表找规律,发现结果是,2的(a二进制位为1总数)次方 代码 #include<bits/stdc++.h> using namespace std; #define ll long ...
- PairWork-电梯调度程序结对编程【附加题】
1 接口改进 1) 之前判断电梯是否闲置的函数不太好理解,重新修改了,如下所示: //是否停顿状态(停止的以及开门间隔>=0) public bool IsIdle { get { return ...
- git常用命令点击查看
创建git项目仓库 $git init 配置个人登记信息,这样团队协作的时候,就可以看到哪个用户修改过哪些文件的 $git config --global user.name 'cfanbo' $gi ...
- Oracle系列(一): Oracle数据恢复
Oracle数据恢复 在使用Oracle的时候,突然一部小心update或者delete全部数据后怎么办? select * from table as of timestamp to_timest ...
- Windows查看端口被什么进程占用的简单方法----菜鸟养成
1. 还是因为同事告知Oracle的服务器连不上 最后发现改了端口就可以了, 但是很困惑 不知道为什么会这样,然后简单查了下: 命令 netstat -ano 查看监听的端口 baidu出来一个管道 ...
- Jenkins Jfrog Artifactory 以及docker下的pipeline 容器编排实践
1. 测试环境情况: Docker主机 10.24.101.99 JFrog Artifactory 主机 (admin password) jenkinx github原始地址:https://gi ...
- linux学习之centos(四):git的安装
整个流程如下:(参考文章:linux安装git方法) [carsonzhu@localhost 桌面]$ wget https://github.com/git/git/archive/v2.8.3. ...
- codeforces116B
Little Pigs and Wolves CodeForces - 116B Once upon a time there were several little pigs and several ...
- std::binary_serach, std::upper_bound以及std::lower_bound
c++二分查找的用法 主要是 std::binary_serach, std::upper_bound以及std::lower_bound 的用法,示例如下: std::vector<int& ...
- POJ3176-基础DP
很基础的dp题.有一头奶牛想接尽量多的苹果,有w此移动机会. dp[i][w] = max(dp[i-1][w+1] + 能否吃到苹果 ,dp[i-1][w] + 能否吃到苹果) //从上一分钟是否 ...