基本思想,当出现不匹配的时候,就知晓一部分文本内容(因为在匹配失败前已经发生匹配)

P[0 ~ k-1] == P[j-k ~ j-1]

//KMP
#include<iostream>
#include<string.h>
#include<malloc.h>
using namespace std;
void come(string pattern,int next[]){
int i=;
int j=-;
const int m=pattern.length();
next[]=j;//第一个为0
for(int i=;i<m;i++){
while(j>-&&pattern[j+]!=pattern[i]) j=next[j]; //恢复0 恢复的地方
if(pattern[i]==pattern[j+]) j++;
next[i]=j;
}
}
/*void com(const char *pattern,int next[]){ //当匹配后跳转的地方next[i]----->pattern[j]
int i=1;
int j=-1;
const int m=strlen(pattern);
next[0]=j;//第一个为0 for(int i=1;i<m;i++){
while(j>-1&&pattern[j+1]!=pattern[i]) j=next[j]; //恢复0 恢复的地方
if(pattern[i]==pattern[j+1]) j++;
next[i]=j;
}
} */
/*int kmp(const char *text,const char *pattern){
int i;
int j=-1;
const int n=strlen(text);
const int m=strlen(pattern);
if(n==0&&m==0) return 0;
if(m==0) return 0;
int *next=(int*)malloc(sizeof(int)*m);
com(pattern,next);
for(i=0;i<n;i++) {
while(j>-1&&pattern[j+1]!=text[i]) j=next[j];
if(text[i]==pattern[j+1]) j++;
if(j==m-1) {
free(next);
return i-j;
}
}
free(next);
return -1;
}*/
int Kmp(string text,string pattern){
int i;
int j=-;
const int n=text.length();
const int m=pattern.length();
if(n==&&m==) return ;
if(m==) return ;
int next[m];
come(pattern,next);
for(i=;i<n;i++) {
while(j>-&&pattern[j+]!=text[i]) j=next[j];
if(text[i]==pattern[j+]) j++;
if(j==m-) {
// free(next);
return i-j;
}
}
// free(next);
return -;
}
int main()
{
// char text[]="ABC ABCDA ABCDABCDABCDABDE";
// char pattern[]="ABCDABD";
// char *ch=text;
string text="ABC ABCDA ABCDABCDABCDABDE";
string pattern="ABCDABD";
int i=Kmp(text,pattern);
// if(i>=0) printf("%s\n",ch+i);
cout<<i<<endl;
return ;
}

我不晓得看了多少次kmp算法了,感觉还是要写博客,不然的话算法这个东西,太容易忘记了。。。

分析:

文本字符串长度为n,模式串长度为m,创建数组next[0...m-1],做一个标记,是对自身的标记

//KMP
#include<iostream>
#include<string.h>
#include<malloc.h>
using namespace std;
void come(string pattern,int next[]){
int i=;
int j=-;
const int m=pattern.length();
next[]=j;//第一个为-1 0-(-1)==1 转移1
for(int i=;i<m;i++){
while(j>-&&pattern[j+]!=pattern[i]) j=next[j]; //恢复0 恢复的地方
if(pattern[i]==pattern[j+]) j++;
next[i]=j;
}
} int Kmp(string text,string pattern){
int i;
int j=-;
const int n=text.length();
const int m=pattern.length();
if(n==&&m==) return ;
if(m==) return ;
int next[m];
come(pattern,next);
for(i=;i<n;i++) {
if(j>-&&pattern[j+]!=text[i]) j=next[j];
if(text[i]==pattern[j+]) j++;
if(j==m-)
return i-j;
}
return -;
}
int main()
{
string text="ABC ABCDA ABCDABCDABCDABDE";
string pattern="ABCDABD";
int i=Kmp(text,pattern);
cout<<i<<endl;
return ;
}

测试数据:

ABC ABCDA ABCDABCDABCDABDE
ABCDABD

字符串的查找KMP的更多相关文章

  1. c算法:字符串查找-KMP算法

    /* *用KMP算法实现字符串匹配搜索方法 *该程序实现的功能是搜索本目录下的所有文件的内容是否与给定的 *字符串匹配,如果匹配,则输出文件名:包含该字符串的行 *待搜索的目标串搜索指针移动位数 = ...

  2. 字符串匹配算法之kmp算法

    kmp算法是一种效率非常高的字符串匹配算法,是由Knuth,Morris,Pratt共同提出的模式匹配算法,所以简称KMP算法 算法思想 在一个字符串中查找另一个字符串时,会遇到如下图的情况 我们通常 ...

  3. Python 细聊从暴力(BF)字符串匹配算法到 KMP 算法之间的精妙变化

    1. 字符串匹配算法 所谓字符串匹配算法,简单地说就是在一个目标字符串中查找是否存在另一个模式字符串.如在字符串 "ABCDEFG" 中查找是否存在 "EF" ...

  4. [算法2-数组与字符串的查找与匹配] (.NET源码学习)

    [算法2-数组与字符串的查找与匹配] (.NET源码学习) 关键词:1. 数组查找(算法)   2. 字符串查找(算法)   3. C#中的String(源码)   4. 特性Attribute 与内 ...

  5. Matlab 之 字符串数组查找

    Matlab的优势在于向量操作,字符串操作往往费时费力,但是如果能充分利用Matlab自带的一些函数,也可以取得不错的效果.下面就介绍一下字符串数组查找的小技巧. 字符串数组我通常会选择应用cell格 ...

  6. C#:比较二个字符串,查找出相同字数和差异字符

            ;; i < n; i++)             {                 ) == s2.Substring(i, ))                 /*同位 ...

  7. 数据结构学习之字符串匹配算法(BF||KMP)

    数据结构学习之字符串匹配算法(BF||KMP) 0x1 实验目的 ​ 通过实验深入了解字符串常用的匹配算法(BF暴力匹配.KMP.优化KMP算法)思想. 0x2 实验要求 ​ 编写出BF暴力匹配.KM ...

  8. 1.3 正则表达式和Python语言-1.3.5使用 search()在一个字符串中查找模式(搜索与匹配 的对比)

    1.3.5 使用 search()在一个字符串中查找模式(搜索与匹配的对比) 其实,想要搜索的模式出现在一个字符串中间部分的概率,远大于出现在字符串起始部分的概率.这也就是 search()派上用场的 ...

  9. ZT 输入一个字符串,查找它的第一个数字串,并返回其个数

    /*查找字符串中的数字串问题 输入一个字符串,查找它的第一个数字串,并返回其个数 */ #include <stdio.h> char firstnum(char *input,char ...

随机推荐

  1. AngularJS学习之旅—AngularJS 表达式(二)

    1.AngularJS 表达式 AngularJS 表达式写在双大括号内:{{ expression }}. AngularJS 表达式把数据绑定到 HTML,这与 ng-bind 指令有异曲同工之妙 ...

  2. Windows Server 2016-域站点复制查询

    了解了有关站点复制概念性内容后,后续几章节我们会围绕站点复制相关内容对域控的日常复制.维护等进行简单介绍.本章为大家带来有关域控站点复制查询的相关内容,希望大家可以喜欢.站点内域控制器之间的复制拓扑由 ...

  3. 一次线上问题引发的对于C#中相等判断的思考

    线上报来一个问题,说用户的数据丢失了.开发经过紧张的调查.终于找到了原因. if (newData.GetValue(rowIndex) == oldData.GetValue(rowIndex)) ...

  4. Android项目的targetSDK>=23,在低于Android6.0的部分测试机(类似华为)上运行时出现的系统权限问题

    相信大家对Android6.0以上的动态权限已经有所了解,很多童鞋也已经跃跃欲试地将自己项目的targetSDK升级到了23及其以上,很不幸的是我也成为了其中一员,然而我还是图样图森破了,升级之后的问 ...

  5. SAP 维护视图创建与修改

    维护视图创建与修改 维护视图创建 T-CODE:SE54 维护ABAP数据字典 维护已生产的对象 注意:当维护视图修改后,需要删除已生成的对象,重新创建已生成的对象,否则无法显示,这个小窍门我花了半天 ...

  6. XSS 漏洞原理及防御方法

    XSS跨站脚本攻击:两种情况.一种通过外部输入然后直接在浏览器端触发,即反射型XSS:还有一种则是先把利用代码保存在数据库或文件中,当web程序读取利用代码并输出在页面上时触发漏洞,即存储型XSS.D ...

  7. 简述KVM架构和Xen架构

    暑假最后一篇更新,因为,,,明天我就回学校了. 以下均为个人理解,如果有不对的地方还望各位dalao不吝赐教. 虚拟化 虚拟化是通过Hypervisor程序实现的,Hypervisor的作用是将硬件虚 ...

  8. Linux 小知识翻译 - 「syslog」

    这次聊聊「syslog」. 上次聊了「日志」(lgo).这次说起syslog,一看到log(日志)就明白是怎么回事了.syslog是获取系统日志的工具. 很多UINIX系的OS都采用了这个程序,它承担 ...

  9. February 11th, 2018 Week 7th Sunday

    Grasp all, lose all. 欲尽得,必尽失. Not to be greedy and not to try to get everything. Our time, energy an ...

  10. vue-router 管理视图详解

    什么是路由 在web开发中,路由是指根据url分配到对应的处理程序,当访问不同的url就会切换到对应的处理程序 在vue中一个url对应的就是一个组件,当访问不同的url,对应的组件就会呈现到页面中 ...