0050 KMP匹配算法的C++实现

19 篇文章 0 订阅
19 篇文章 0 订阅

引言:

    KMP模式匹配算法在搜索与索引中是算法基础(?)

    KMP匹配分两步:

1)根据要查找的字符串计算出next值;

2)利用next值来控制移动位置,实现高效匹配,不做多余的比较。

#include <iostream>
#include<string>
using namespace std;
//产生next值
void genKMPNext(int* next,string s)
{
	int i=0;
	int j=-1;
	next[0] = -1;
	while(i<s.length()-1)
	{
		while(j>=0&&s[i] != s[j])
			j = next[j];
		i++;
		j++;
		if(s[i] ==s[j])
			next[i] = next[j];
		else
			next[i] = j;
	}
}
//利用next值进行KMP算法
int KMP(string cs,string s)
{
	int i;
	int j;
	int *next = (int*)malloc(sizeof(int)*s.length());

	genKMPNext(next,s);

	for (i=0,j=0;i<s.length()&&j<cs.length();  )
	{
		if (s[i]==cs[j])
		{	i++;
			j++;
		}
		else if(next[i]>=0)
			i = next[i];
		else
		{
			i=0;j++;
		}
	}
		if(i>=s.length())
			return j-s.length();
		else
			return -1;
}
//主函数部分
int main()
{
    string cs="googlegood";  //一个长字符串
	string s="good";                //目标串,即要在cs中寻找的字符串
	int pos=KMP(cs,s);   //找完后记录在cs的某个位置起
	if(pos>=0)
		cout<<"你匹配的字符串存在于原字符串的第"<<pos+1<<"个位置开始"<<endl;
	else
		cout<<"你匹配的字符串不存在"<<endl;

    return 0;
}

当s="god"

---------------------------------------------------------2016.6.4更新,互动性地模式匹配-------------------------------

在ubuntu14.04编程实现:

#include<string>
#include<iostream>
#include<stdlib.h>
using namespace std;

void genNext(int *next,string s)
{
	int i=0;
	int j=-1;
	
	next[0] = -1;
	
	while(i<s.length()-1)
	{
		while(j>=0&&s[i]!=s[j])
			j = next[j];
		i++;
		j++;
		if(s[i]==s[j])
			next[i] = next[j];
		else
			next[i] = j;
	}
}

int Find(string cs,string s)
{
	int i,j,*next = (int*)malloc(sizeof(int)*s.length());
	genNext(next,s);

	for(i=0,j=0;i<s.length()&&j<=cs.length(); )
		{
			if(s[i]==cs[j])
			{i++;j++;}
			else if(next[i]>=0)
			i=next[i];
			else
			{i=0;j++;}
			
		}
	if(i>=s.length())
		return j-s.length();
	else
		return -1;

}


int main()
{
	string cs;  
	string s; 
	cout<<"请输入原始字符串:"<<endl;
	cin>>cs;
	cout<<"请输入要查找的子字符串:"<<endl;
	cin>>s;
	int len =s.length();
	int next[len];
	int pos = Find(cs,s);
	if(pos>=0)
	cout<<"所匹配的字符在原字符串从左往右数的第"<<pos+1<<"个位置开始出现"<<endl;
	else
	cout<<"你所匹配的字符串在源字符串中不存在"<<endl;
	
	return 0;
}


 匹配上和没匹配上的结果显示为: 


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值