方法是利用count[i][j]來記錄以(i,j)為左上方,且大小為X,Y的矩形中含有多少個完整行與P矩陣對應行完全相同。
所以,如果在T矩陣的第r行的第c列開始與P的第i行匹配,那麼count[r-i][c]++;
最後判斷是否有count[][]==X;
#include"stdio.h"#include"string.h"#include"stdlib.h"#include"queue"using namespace std;#define maxnode (100*100+10)#define sigma_size 26int N,M,X,Y;char map[1005][1005];int cnt[1005][1005];struct AC_automation{struct node{int next[sigma_size];int val;//樹節點的附加資訊int fail;//儲存節點的失配指標vector<int>line;//記錄該單詞所在的行數,可能多個行的單詞相等void init(){memset(next,0,sizeof(next));line.clear();fail = val = 0;}}ch[maxnode];//用來儲存Trie樹int sz;//整棵樹節點的總數 int idx(char c){return c - 'a';//對於小寫字母集,獲得c的編號}void init(){sz = 1;ch[0].init();}void insert(char *s,int v){int u = 0,len = strlen(s);for(int i = 0 ; i < len ; i ++){int c = idx(s[i]);if(ch[u].next[c] == 0){ch[sz].init();ch[u].next[c] = sz++;}u = ch[u].next[c];}ch[u].val = 1;ch[u].line.push_back(v);}//利用bfs得到失配指標failvoid get_fail(){queue<int>Q;for(int i = 0 ; i < sigma_size; i ++)if(ch[0].next[i] != 0)Q.push(ch[0].next[i]);while(!Q.empty()){int temp = Q.front();Q.pop();for(int i = 0 ; i < sigma_size; i ++){if(ch[temp].next[i] != 0){Q.push(ch[temp].next[i]);int fail_temp = ch[temp].fail;//關鍵步驟,如果fail指標所指的節點沒有('a'+i)這個子節點,繼續遞迴,直到fail_temp指向0節點,即根節點while(fail_temp > 0 && ch[fail_temp].next[i] == 0) fail_temp = ch[fail_temp].fail;if(ch[fail_temp].next[i] != 0)//如果fail_temp節點的子節點有('a'+i)這個字元fail_temp = ch[fail_temp].next[i];ch[ch[temp].next[i]].fail = fail_temp; //子節點的失配節點由父節點節點決定}}}}//尋找text[]總共有多少個單詞void find(char *text,int x){int len = strlen(text);int node = 0,fail_temp = 0;for(int i = 0 ; i < len ; i ++){int character = idx(text[i]);while(fail_temp > 0 && ch[fail_temp].next[character] == 0)//若沒有text[i]這個字元,則使用失配指標繼續在Trie樹上遍曆fail_temp = ch[fail_temp].fail;if(ch[fail_temp].next[character] != 0){//此時找到了text[i]這個字元fail_temp = ch[fail_temp].next[character];int fail_temp2 = fail_temp;//此處必須有另一個變數來記錄失配的時候的下標while(fail_temp2 > 0 && ch[fail_temp2].val){ for(int j = 0 ; j < ch[fail_temp2].line.size(); j ++){//枚舉該單詞所在的所有行int temp = ch[fail_temp2].line[j];if(x >= temp)cnt[x-temp][i] ++;}fail_temp2 = ch[fail_temp2].fail;}}}}}AC;int main(){int T;scanf("%d",&T);while(T--){AC.init();memset(cnt,0,sizeof(cnt));scanf("%d%d",&N,&M);for(int i = 0 ; i < N ; i ++)scanf("%s",map[i]);scanf("%d%d",&X,&Y);char str_temp[105];for(int i = 0 ; i < X; i++){scanf("%s",str_temp);AC.insert(str_temp,i);}AC.get_fail();for(int i = 0 ; i < N ; i++){AC.find(map[i],i);}int ans = 0;for(int i = 0 ; i < N; i ++){for(int j = 0 ; j < M ; j ++){if(cnt[i][j] == X)ans++;}}printf("%d\n",ans);}return 0;}