CCF201409-3 字符串匹配 初級KMP 一句判斷大小寫鎖定

問題描述
  給出一個字符串和多行文字,在這些文字中找到字符串出現的那些行。你的程序還需支持大小寫敏感選項:當選項打開時,表示同一個字母的大寫和小寫看作不同的字符;當選項關閉時,表示同一個字母的大寫和小寫看作相同的字符。
輸入格式
  輸入的第一行包含一個字符串S,由大小寫英文字母組成。
  第二行包含一個數字,表示大小寫敏感的選項,當數字爲0時表示大小寫不敏感,當數字爲1時表示大小寫敏感。
  第三行包含一個整數n,表示給出的文字的行數。
  接下來n行,每行包含一個字符串,字符串由大小寫英文字母組成,不含空格和其他字符。
輸出格式
  輸出多行,每行包含一個字符串,按出現的順序依次給出那些包含了字符串S的行。
樣例輸入
Hello
1
5
HelloWorld
HiHiHelloHiHi
GrepIsAGreatTool
HELLO
HELLOisNOTHello
樣例輸出
HelloWorld
HiHiHelloHiHi
HELLOisNOTHello
樣例說明
  在上面的樣例中,第四個字符串雖然也是Hello,但是大小寫不正確。如果將輸入的第二行改爲0,則第四個字符串應該輸出。
評測用例規模與約定

  1<=n<=100,每個字符串的長度不超過100。



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

#define MAX 100+5

const int cap = 'a' - 'A';

int nx[MAX];

void pre(string s){
	nx[0] = -1;
	int j = 0, k = -1;
	while (j < s.length()){
		if ((k == -1) || (s[j] == s[k])){
			j++;
			k++;
			nx[j] = k;
		}
		else k = nx[k];
	}
}

bool kmp(string s,string cs,int c){
	int z = 0;
	for (int i = 0; i <= s.length(); i++){
		if (z >= cs.length()){
			return true;
		}
		if (i == s.length()) return false;
		
		if (s[i] == cs[z] || abs(s[i]-cs[z])==cap*c){
			z++;
		}
		else{
			while (nx[z] != -1 && (s[i] != cs[z] && abs(s[i] - cs[z]) != cap*c)){ // 大小寫
				z = nx[z];
			}
		}
	}
}

int main(){
	string s;
	cin >> s;
	pre(s);
	int c,n;
	cin >> c >> n;
	while (n--){
		string ss;
		cin >> ss;
		if (kmp(ss, s, abs(c-1))){
			cout << ss << endl;
		}
	}
	return 0;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章