【CCF】字符串匹配

试题名称: 字符串匹配 
时间限制: 1.0s 
内存限制: 256.0MB 
问题描述: 问题描述
  给出一个字符串和多行文字,在这些文字中找到字符串出现的那些行。你的程序还需支持大小写敏感选项:当选项打开时,表示同一个字母的大写和小写看作不同的字符;当选项关闭时,表示同一个字母的大写和小写看作相同的字符。
输入格式
  输入的第一行包含一个字符串S,由大小写英文字母组成。
  第二行包含一个数字,表示大小写敏感的选项,当数字为0时表示大小写不敏感,当数字为1时表示大小写敏感。
  第三行包含一个整数n,表示给出的文字的行数。
  接下来n行,每行包含一个字符串,字符串由大小写英文字母组成,不含空格和其他字符。
输出格式
  输出多行,每行包含一个字符串,按出现的顺序依次给出那些包含了字符串S的行。
样例输入
Hello
1
5
HelloWorld
HiHiHelloHiHi
GrepIsAGreatTool
HELLO
HELLOisNOTHello
样例输出
HelloWorld
HiHiHelloHiHi
HELLOisNOTHello
样例说明
  在上面的样例中,第四个字符串虽然也是Hello,但是大小写不正确。如果将输入的第二行改为0,则第四个字符串应该输出。
评测用例规模与约定

  1<=n<=100,每个字符串的长度不超过100。 


使用KMP算法轻松解决:

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

class myString 
{ 
protected: 
    int size; 
    string mainstr; 
    void GetNext(string p,int next[]); 
    int KMPFind(string p,int pos,int next[]); 
public: 
    myString(); 
    ~myString(); 
    void SetVal(string sp); 
    int KMPFindSubstr(string p,int pos); 
}; 
  
myString::myString() 
{ 
    size=0; 
    mainstr=""; 
} 
  
myString::~myString() 
{ 
    size=0; 
    mainstr=""; 
} 
  
void myString::SetVal(string sp) 
{ 
    mainstr=""; 
    mainstr.assign(sp); 
    size=mainstr.length(); 
} 
  
int myString::KMPFindSubstr(string p,int pos) 
{ 
    int L=p.length(); 
    int *next=new int[L]; 
    GetNext(p,next); 
    int v=-1; 
    v=KMPFind(p,pos,next); 
    delete[]next; 
    return v; 
} 
void myString::GetNext(string p,int next[]) 
{ 
	int i=0,j=-1;next[0]=-1;
	while(i<p.length()-1)
	{
		if(j==-1||p[i]==p[j])
		{
			i++;
			j++;
			next[i]=j;
		}
		else j=next[j];
	}
} 

bool compare(int a,int b){
	if(!key){
		if(a>=65 && a<=90){
			a+=32;
		}
		if(b>=65 && b<=90){
			b+=32;
		}
	}
	return a==b;
}

int myString::KMPFind(string p,int pos,int next[]) 
{ 
	int i=pos,j=1,k;
	while(i<=mainstr.length()&&j<=p.length())
	{	
		if(j==0||compare(mainstr[i-1],p[j-1]))
		{
			i++;
			j++;
		}
		else j=next[j-1]+1;

	}
	if(j>p.length())return i-p.length();
	else return 0;
}

int main() 
{ 
    int T; 
    string _P,_F; 
	myString _M; 
	cin>>_F; 
	cin>>key;
    cin>>T; 
	while(T--) 
	{
		cin>>_P;
		_M.SetVal(_P); 
		if(_M.KMPFindSubstr(_F,1)){
			cout<<_P<<endl;
		}
	} 
	return 0; 
} 




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值