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;
} 

猜你喜欢

转载自blog.csdn.net/weixin_45845039/article/details/108905362