KMP算法可以在O(n+m)的时间数量级上完成模式匹配,其做法在于:没当一次匹配过程中出现字符比较不等时,不需要回溯指针,而是利用已经得到的“部分匹配”的结果将模式向右“滑动”尽可能远的一段距离后,继续进行比较。

在KMP算法中主要是先得到子字符串的next数组,计算next数组方法如下:

(1)、next[1]=0,next[1]=1

(2)、后面求解每一位的next[j]值时,根据j的前一位进行比较,令k=next[j-1];

(3)、将s[j-1]于s[k]进行比较:

  如果相等,则令该next[j]=k+1

  如果不相等,令k=next[k],若k不等于0,跳到(3),否则,next[j]=1

eg:

如下图j=4时,此时前面的next数组为0 1 1,所以k=next[3]=1 ,由于s[j-1]=s[3]=a、s[k]=s[1]=a,所以s[j]=s[4]=1+1=2

如下图j=5时,next={0,1,1,2},k=2,s[j-1]=a,s[k]=b,所以k=next[k]=next[2]=1,此时s[k]=s[1]=a,所以s[j]=s[5]=1+1=2

比如子字符串为:abaabcac,计算如下图

得到子字符串之后,在字符串匹配的时候,子字符串不再是移动1个字符串,而是移动next(j)个位置,代码如:(这里需要注意,next数组是从1开始的,没有0)

c++实现:

#include <iostream>
#include <stdlib.h>
#include <vector>
using namespace std; //利用模版进行输出
template <typename T>
void print(vector<T> a)
{
typename vector<T>::iterator it;//前面要加typename,要不会出错
for(it=++a.begin();it!=a.end();it++)
{
cout<<*it;
}
} vector<int> next_str={-,,};//为了使下标从1开始,在前面添加一个-1
void next_list(vector<char> v,int n)//得到子字符串的next数组
{
int j=,k;
while(j<=n)
{
k=next_str[j-];
if(v[j-]==v[k])
{
k++;
next_str.push_back(k);
}
else
{
k=next_str[k];
while(true)
{
if(k==)
{
next_str.push_back();
break;
}
if(v[j-]==v[k])
{
next_str.push_back(++k);
break;
}
else
{
k=next_str[k];
}
}
}
j++;
}
} int get_index(vector<char> l,vector<char> s,int n,int m)
{
int i=,j=;
while(i<=n&&j<m)
{
if(j==||l[i]==s[j])
{
i++;
j++;
}
else
{
j=next_str[j];
}
}
if(j==m)
{
return i-j+;
}
else
{
return -;
}
} int main()
{ int n;
cin>>n;
vector<char> longstr={'#'};//为了下标从1开始,添加一个’#‘
char c;
for(int i=;i<n;i++)
{
cin>>c;
longstr.push_back(c);
} int m;
cin>>m;
vector<char> shortstr={'#'};//为了下标从1开始,添加一个’#‘
for(int i=;i<m;i++)
{
cin>>c;
shortstr.push_back(c);
} // int n=20,m=8;
// vector<char> longstr={'#','b','c','a','a','b','a','c','a','b','a','a','b','c','a','c','a','b','c','d','a'};
// vector<char> shortstr={'#','a','b','a','a','b','c','a','c'}; next_list(shortstr,m);
print(next_str);
cout<<endl; int index=get_index(longstr,shortstr,n,m);
if(index>=)
{
print(shortstr);
cout<<"在";
print(longstr);
cout<<"中,从位置"<<index<<"开始"<< endl;
}
else
{
print(shortstr);
cout<<"不在";
print(longstr);
cout<<"中endl";
}
return ;
}

python实现:

#-*- coding:utf- -*-

class KMP:

    def __init__(self,s_long,s_short):
self.s_long=s_long
self.s_short=s_short
self.flag= def get_nextList(self):
l=[,]
for i in range(,len(self.s_short)):
l.append(self.get_num_1(self.s_short[:i]))
print l
b=
a=
while True:
if self.s_short[a]==self.s_long[b]:
a+=
b+=
else:
a=l[a]-
if a==-:
a +=
b +=
if self.s_short==self.s_long[b:b+len(self.s_short)]:
break
if b==len(self.s_long):
return
return b+ '''
功能(见图2、):获得子字符串的next数组,和第一张图方法比一样,更容易理解
s:用于存储该字符前面所有的子字符串(注意子字符串是从这个字符串开始从后往前,长度慢慢增长)
while循环:用于确定前面最长重复的字符串(注意,应该从长的开始匹配,且必须从第一个字符开始)
返回最长字符串长度+
'''
def get_num_1(self,string):
s=[]
for i in range(,len(string)):
s.append(string[len(string)-i:len(string)])
while s:
temp=s.pop()
n=len(temp)
if temp==string[:n+]:
return len(temp)+
return long=raw_input()
short=raw_input()
print KMP(long,short).get_nextList()

KMP-字符串模式匹配(c++/python实现)的更多相关文章

  1. KMP字符串模式匹配详解(转)

    来自CSDN     A_B_C_ABC 网友 KMP字符串模式匹配通俗点说就是一种在一个字符串中定位另一个串的高效算法.简单匹配算法的时间复杂度为O(m*n);KMP匹配算法.可以证明它的时间复杂度 ...

  2. KMP字符串模式匹配详解(zz)

    刚看到位兄弟也贴了份KMP算法说明,但本人觉得说的不是很详细,当初我在看这个算法的时候也看的头晕昏昏的,我贴的这份也是网上找的.且听详细分解: KMP字符串模式匹配详解 来自CSDN     A_B_ ...

  3. KMP字符串模式匹配详解

    KMP字符串模式匹配详解 http://www.cppblog.com/oosky/archive/2006/07/06/9486.html

  4. KMP字符串模式匹配学习笔记

    KMP算法实验 1.编程计算模式串(子串)的next值.2.利用KMP算法在主串中找到模式串的位置. 参考代码:---------int getNexlVal( char * s,  int j)// ...

  5. 字符串模式匹配KMP算法

    一篇不错的博客:http://www.cnblogs.com/dolphin0520/archive/2011/08/24/2151846.html KMP字符串模式匹配通俗点说就是一种在一个字符串中 ...

  6. 『字符串模式匹配 KMP』

    字符串模式匹配 我们要先了解一下问题是什么. 模式匹配是数据结构中字符串的一种基本运算,给定一个子串,要求在某个字符串中找出与该子串相同的所有子串,这就是模式匹配. KMP 然后我们来认识一下今天的主 ...

  7. 字符串模式匹配sunday算法

    文字部分转自:http://www.cnblogs.com/mr-ghostaqi/p/4285868.html 代码是我自己写的 今天在做LeetCode的时候,碰到一个写字符串匹配的题目: htt ...

  8. json数据处理:读取文件中的json字符串,转为python字典

    方法1: 读取文件中的json字符串, 再用json.loads转为python字典 import json str_file = './960x540/config.json' with open( ...

  9. BM和KMP字符串匹配算法学习

    BM和KMP字符串匹配算法学习 分类: 研究与学习 字符串匹配BM(Boyer-Moore)算法学习心得 http://www.cnblogs.com/a180285/archive/2011/12/ ...

  10. MySQL九读书笔记 字符串模式匹配

    当我们使用查询,条件常常会遇到模糊查询.的模糊查询相关的字符串模式匹配. 这里,主要约两:标准SQL模式匹配.扩展正则表达式模式匹配.     一.标准的SQL模式匹配 SQL的模式匹配同意你使用&q ...

随机推荐

  1. Unit Testing of Spring MVC

    试验1:做的条目不发现首先,我们必须确保我们的应用是工作性质所做条目不发现.我们可以写的测试以确保通过以下步骤: 1.配置的模拟对象时抛出一个todonotfoundexception findbyi ...

  2. UVa 12545 Bits Equalizer (贪心)

    题意:给出两个等长的字符串,0可以变成1,?可以变成0和1,可以任意交换s中任意两个字符的位置,问从s变成t至少需要多少次操作. 析:先说我的思路,我看到这应该是贪心,首先,如果先判断s能不能变成t, ...

  3. POJ 3320 Jessica's Reading Problem (滑动窗口)

    题意:给定一个序列,求一个最短区间,使得这个区间包含所有的种类数. 析:最近刚做了几个滑动窗口的题,这个很明显也是,肯定不能暴力啊,时间承受不了啊,所以 我们使用滑动窗口来解决,要算出所有的种数,我用 ...

  4. @Autowired 和 @Qualifier

    一 无冲突 bean工厂 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns=" ...

  5. day3之函数的初始及进阶

    函数初始 函数的定义与调用 ''' def 函数名 (参数): 函数体 函数名:设定与变量相同 执行函数: 函数名() ''' 函数的返回值 # 函数返回值 return ''' 1.遇到return ...

  6. crosss compile VLC with OpenMAX on ARM board(RockChip RK3399),in order to use Hard Acceleration when decode video

    reference:http://www.x90x90x90.com/en/raspberry-pi-3-howto-compile-vlc-with-hardware-acceleration/ 1 ...

  7. ubuntu18.04 编译安装 apache php

    1. apache apache 需要依赖几个模块:apr, apr-util, pcre,也分别源码安装. 1.1 编译安装 1.1.1 apr apr-util 下载地址:http://apr.a ...

  8. Android SQLiteOpenHelper Sqlite数据库的创建与打开

    Android Sqlite数据库是一个怎样的数据库? 答:是一种嵌入式小型设备,移动设备,的数据库,应用在穿戴设备(例如:智能手表,计算手环 等等),移动设备(例如:Android系统类型的手机 等 ...

  9. zabbix-server启动报错解决

    启动zabbix-server有如下报错: 29171:20180714:084911.367 cannot start alert manager service: Cannot bind sock ...

  10. python的数据存储

    Python存储数据 使用json.dump()和json.load() 不管专注的是什么,程序都把用户提供的信息存储在列表和字典等数据结构中.用户关闭程序时,你几乎总是要保存他们提供的信息:一种简单 ...