牛客oj 習題4.7String Matching(KMP)&&習題4.6字符串匹配

 

練KMP我認爲沒什麼技巧,背代碼就完事了。我的口訣:(僅限於自己理解)

(1)、先回溯主串後回溯子串,回溯哪個哪個爲負一;

(2)、推nextTable時拿子串對應的下標開刀。

PS:這題把nextTable數組換成next數組居然有歧義,這辣雞編譯器居然還會把next數組設成關鍵字,第一次碰到這種錯害得我檢查了一個小時,真是絕了。

 

 

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#include <vector>
#include <climits>
 
using namespace std;
 
const int MAXN = 1000005;
const int INF = INT_MAX;
 
int nextTable[MAXN];
 
void getNext(string &text, string &pattern){
    int n = text.size();
    int m = pattern.size();
    int i, j;
    j = 0;
    nextTable[j] = -1;
    i = nextTable[j];
    while(j < m){
        if(i == -1 || pattern[i] == pattern[j]){
            i++;
            j++;
            nextTable[j] = i;
        }
        else{
            i = nextTable[i];
        }
    }
}
 
int KMP(string &text, string &pattern){
    getNext(text, pattern);
    int n = text.size();
    int m = pattern.size();
    int i, j, ans;
    i = j = ans = 0;
    while(i < n && j < m){
        if(j == -1 || text[i] == pattern[j]){
            i++;
            j++;
        }
        else{
            j = nextTable[j];
        }
        if(j == m){
            ans++;
            j = nextTable[j];
        }
    }
    return ans;
}
 
int main(){
//  freopen("in.txt", "r", stdin);
    string text, pattern;
    while(cin >> text >> pattern){
        printf("%d\n", KMP(text, pattern));
    }
    return 0;
}

 

 

連續兩個遇到牛客的辣雞題,上一個是編譯器的問題,這個是題目沒說清楚。明明題目中說了"並且可以有一個用中括號表示的模式匹配",是隻有一個括號,結果後來卡在688那個例子傻了半天,無奈看評論發現不只有一個括號。nnd,只能重寫一遍匹配了。有點不舒服,A了是運氣。

 

 

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#include <vector>
#include <cctype>
#include <climits>
 
using namespace std;
 
const int MAXN = 1005;
const int INF = INT_MAX;
 
int main(){
  //  freopen("in.txt", "r", stdin);
    int n;
    string pattern;
    string table[MAXN], tabletmp[MAXN];
    while(~scanf("%d", &n)){
    	//if(n == 0) break;
        for(int i = 0; i < n; i++){
        	cin >> table[i];
        }
        cin >> pattern;
        //初始化 
        for(int i = 0; i < n; i++){
        	tabletmp[i] = table[i];
        	for(int j = 0; j < tabletmp[i].size(); j++){
        		if(isupper(tabletmp[i][j])) tabletmp[i][j] = tolower(tabletmp[i][j]);
        	}
        }
        for(int i = 0; i < pattern.size(); i++){
        	if(isupper(pattern[i])) pattern[i] = tolower(pattern[i]);
        }
        //模式串匹配 
        for(int i = 0; i < n; i++){
        	bool flag1 = true;
        	int num = 0;
        	for(int j = 0; j < tabletmp[i].size(); j++){
        		if(pattern[num] == '['){
        			if(pattern[num+1] == ']') continue;
        			bool flag2 = false;//初始爲匹配不到 
        			num++;
        			while(pattern[num] != ']'){
        				if(pattern[num] == tabletmp[i][j]) flag2 = true;//匹配到 
        				num++;
        			}
        			if(!flag2){
        				flag1 = false;
        				break;
        			}
        			num++; 
        			continue;
        		}
        		if(pattern[num] != tabletmp[i][j]){
        			flag1 = false;
        			break;
        		}
        		num++;
        	}
        	if(num != pattern.size()) flag1 = false;
        	if(flag1) cout << i+1 << " " << table[i] << endl; 
        }
    }
    return 0;
}

 

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