字符串应用-实现KMP匹配算法

题目描述

给定一个主串S和子串P,使用KMP算法查找子串P在主串S中存在的位置,若子串P在主串S中存在,则输出与子串P中第一字符相等的字符在主串S中的序号;若不存在则输出“no”

程序输入格式:主串S 子串P;

程序输出格式:输出与子串P中第一字符相等的字符在主串S中的序号;

输入样例:ababcabcacbab abcac

输出样例:5

附件

样例输入输出
样例1
输入:
ababcabcacbab abcac
输出:
5
样例2
输入:
ABCDABCDABDE DBAEA
输出:
no


#include <iostream>
#include <string>
using namespace std;

void getnext(string t,int next[])
{
	next[1]=0;
	int i=1,j=0;
	while (i<t.length()-1)
	{
		if (j==0||t[i]==t[j])
		{
			++i;++j;
			next[i]=j;
		}
		else
			j=next[j];
	}
	//优化版
	for (int m=2;m<t.length();m++)
	{
		if (t[m]==t[next[m]])
		{
			next[m]=next[next[m]];
		}
	}
	
}

void Index_KMP(string s,string t)
{
	int *next=new int[t.length()+1];
	getnext(t,next);
    /*for (int i = 1; i < t.length(); i++)
	{
		cout<<next[i]<<" ";
	}
	cout<<endl;
	*/
	int i=1;int j=1;
	while (i<s.length()&&j<t.length())
	{
		if (j==0||s[i]==t[j])
		{
			++i;++j;
		}
		else
		{
			j=next[j];
		}
	}
	if (j>=t.length())
	{
		
		cout<< i-t.length();
		delete []next;
	}
	else
	{
		
		cout<<"no";
		delete []next;
	   
	}


}




int main()
{
	string s,t;
	cin>>s;
	cin>>t;
	Index_KMP(" "+s," "+t);
system("pause");
return 0;
}

对于这道题有一种next是从-1开始的
但是会出现问题
//这里出现-1大于 .length() or .size() 的情况是因为-1变成无符号是补码全为1超级大
//因为string的size类型是size_t,一般是32位或者64位无符号整数;而-1是int类型,
//在与unsigned int(也可能是unsigned long等等,看你具体编译器)进行比较时会被提升为相应的无符号类型,而-1的二进制补码是全1,
//把全1的二进制码当做无符号数解释的时候是无符号数的最大值,所以-1是最大的。
所以要把t.length() 变成 signed(t.length())再和-1比较

#include <string>
using namespace std;

void getnext(string t,int next[])
{
	next[0]=-1;
	int i=0,j=-1;
	while(i<t.length()-1)
	{
		if (j==-1||t[i]==t[j])
		{
			++i;++j;
			next[i]=j;
		}
		else
		{
			j=next[j];
		}

	}
	//这个优化可有可无
	for (int m=2;m<t.length();m++)
	{
		if (t[m]==t[next[m]])
		{
			next[m]=next[next[m]];
		}
	}
	

}
void kmp(string s,string t)
{
	int *next=new int[t.length()];
	getnext(t,next);
	int i=0,j=0;
	
	
	//这里出现-1大于  .length()  or  .size()  的情况是因为-1变成无符号是补码全为1超级大
	//因为string的size类型是size_t,一般是32位或者64位无符号整数;而-1是int类型,
	//在与unsigned int(也可能是unsigned long等等,看你具体编译器)进行比较时会被提升为相应的无符号类型,而-1的二进制补码是全1,
	//把全1的二进制码当做无符号数解释的时候是无符号数的最大值,所以-1是最大的。


	while (i<s.length()&&j<signed(t.length()))
	{
		if (j==-1||s[i]==t[j])
		{
			++i;++j;
		}
		else
		{
			j=next[j];
		}
	}
	if (j>=signed(t.length()))
	{
		cout<< i-t.length();
		delete []next;
	}
	else
	{

		cout<<"no";
		delete []next;

	}

}

int main()
{
	string s,t;
	cin>>s;
	cin>>t;
	kmp(s,t);
	system("pause");
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值