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算法 ...
随机推荐
- Spring Cloud :断路器集群监控(Turbine)
一. 简介 上一篇文章我们已经实现了对单个服务实例的监控,当然在实际应用中,单个实例的监控数据没有多大的价值,我们更需要的是一个集群系统的监控信息,这时我们就需要引入Turbine.Turb ...
- Dubbo原理和源码解析之服务暴露
github新增仓库 "dubbo-read"(点此查看),集合所有<Dubbo原理和源码解析>系列文章,后续将继续补充该系列,同时将针对Dubbo所做的功能扩展也进行 ...
- 微信小程序navigator
如果是小程序自身页面的跳转 <navigator open-type="navigate" target="self" url="target ...
- 2017BUAA软工第0次作业
第一部分:结缘计算机 1. 你为什么选择计算机专业?你认为你的条件如何?和这些博主比呢? 我在上大学之前,其实一直就没怎么考虑过自己以后想要选什么专业,只知道一个大致的方向一定是理工科.毕竟大学之前, ...
- Docker for windows 入门三(PowerShell命令使用)
- js选择排序。
<script> , , , , , , , ]; ; j<len; j++ ){ // 假设min为最小值 var minIndex = j; var min = arr[j]; ...
- CMake--Set用法
CMake中的set用于给一般变量,缓存变量,环境变量赋值. cmake官方文档set set(<variable> <value> [[CACHE <type> ...
- pandas函数应用
1.管道函数 #!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2018/5/24 15:03 # @Author : zhang cha ...
- python之列表操作(list)
# 列表操作功能汇总 print("列表操作功能汇总") list_demo = ['first', 'second', 'thrid', 'fourth'] # 复制list_d ...
- selenium之封装登陆操作
# selenium 封装登录操作举例 import os, time # from selenium import webdriver class LoginPage(): '''登录模块''' d ...