KMP 串的模式匹配 (25分)(3种方法)

Posted Fmm-PMO

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了KMP 串的模式匹配 (25分)(3种方法)相关的知识,希望对你有一定的参考价值。

给定两个由英文字母组成的字符串 String 和 Pattern,要求找到 Pattern 在 String 中第一次出现的位置,并将此位置后的 String 的子串输出。如果找不到,则输出“Not Found”。

本题旨在测试各种不同的匹配算法在各种数据情况下的表现。各组测试数据特点如下:

数据0:小规模字符串,测试基本正确性;
数据1:随机数据,String 长度为 10​5,Pattern 长度为 10;
数据2:随机数据,String 长度为 10​5,Pattern 长度为 102;
数据3:随机数据,String 长度为 10​5,Pattern 长度为 10​3;
数据4:随机数据,String 长度为 10​5,Pattern 长度为 10​4;
数据5:String 长度为 10​6,Pattern 长度为 105;测试尾字符不匹配的情形;
数据6:String 长度为 106 ,Pattern 长度为 105 ;测试首字符不匹配的情形。
输入格式:
输入第一行给出 String,为由英文字母组成的、长度不超过 10​6 的字符串。第二行给出一个正整数 N(≤10),为待匹配的模式串的个数。随后 N 行,每行给出一个 Pattern,为由英文字母组成的、长度不超过 10​5的字符串。每个字符串都非空,以回车结束。

输出格式:
对每个 Pattern,按照题面要求输出匹配结果。

输入样例:

abcabcabcabcacabxy
3
abcabcacab
cabcabcd
abcabcabcabcacabxyz

输出样例:

abcabcacabxy
Not Found
Not Found

方法一:c++,主要使用字符串截取函数,超时,21分
#include <iostream>
#include <string>
using namespace std;

int main()
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	string s,p;
	int n;
	cin >> s;
	cin >> n;
	for(int i = 0;i<n;i++)
		cin >> p;
		bool flag = false;
		if(p.length()>s.length())
			cout << "Not Found" << endl;
		else
			for(int j = 0;j<=s.length()-p.length();j++)
				if(s[j]==p[0])
					string ss = s.substr(j,p.length());
					if(ss==p)
						cout << s.substr(j) << endl;;
						flag = true;
						break;
					
				
			
			if(!flag)
				cout << "Not Found" << endl;
		
	
	return 0;
 

方法二:学到了一个新的函数,挺好用的,厉害啊!!!附上一篇讲解的博客,注意它的参数是char数组(根据题目数据的要求,选择数组需要开辟的大小),不要把string往里边放!!!,同时注意它的头文件

strstr(str1,str2) 函数

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

int main()
	char s[1000001],p[100001];
	int n;
	cin >> s;
	cin >> n;
	for(int i = 0;i<n;i++)
		cin >> p;
		if(strstr(s,p))
			cout << strstr(s,p) << endl;
		else
			cout << "Not Found" << endl;
	
	return 0;

方法三:按照题目要求乖乖来,使用KMP算法,不要用暴力BF哦(数据大肯定会超时的)
#include <iostream>
#include <string>
#include <cstring>
using namespace std;

int xnext[100001];

void get_next(string s)
	int i,j;
	i = 0;//后缀
	j = -1;//前缀
	xnext[0] = -1;
	while(i<s.length())
		if(j==-1||s[i]==s[j])
			i++;
			j++;
			xnext[i] = j;
		
		else
			j = xnext[j];
	 


int get_index(string s1,string s2)
	int i = 0;
	int j = 0;
	get_next(s2);
	while(i<s1.length())
		if(j==-1||s1[i]==s2[j])
			i++;
			j++;
		
		else
			j = xnext[j];
		if(j==s2.length())
			return i-s2.length();
	
	return -1;


int main()
	string s,p;
	int n;
	cin >> s;
	cin >> n;
	for(int i = 0;i<n;i++)
		cin >> p;
		int res = get_index(s,p);
		if(res==-1)
			cout << "Not Found" << endl;
		else
			cout << s.substr(res) << endl;
	
	return 0;
 

以上是关于KMP 串的模式匹配 (25分)(3种方法)的主要内容,如果未能解决你的问题,请参考以下文章

(王道408考研数据结构)第四章串-第二节:串的模式匹配算法(朴素和KMP)

求出子串(模式串)的next函数值,利用kmp算法实现模式与主串的匹配算法

第四章:2.串 -- 串的模式匹配算法(KMP)

什么是KMP算法?KMP算法推导

串的匹配:朴素匹配&amp;KMP算法

数据结构关于串的KMP算法的理解高手请进