description
小t非常感謝大家幫忙解決了他的上乙個問題。然而病毒侵襲持續中。在小t的不懈努力下,他發現了網路中的「萬惡之源」。這是乙個龐大的病毒**,他有著好多好多的病毒,但是這個**包含的病毒很奇怪,這些病毒的特徵碼很短,而且只包含「英文大寫字元」。當然小t好想好想為民除害,但是小t從來不打沒有準備的戰爭。知己知彼,百戰不殆,小t首先要做的是知道這個病毒**特徵:包含多少不同的病毒,每種病毒出現了多少次。大家能再幫幫他嗎?
input
第一行,乙個整數n(1<=n<=1000),表示病毒特徵碼的個數。
接下來n行,每行表示乙個病毒特徵碼,特徵碼字串長度在1―50之間,並且只包含「英文大寫字元」。任意兩個病毒特徵碼,不會完全相同。
在這之後一行,表示「萬惡之源」**原始碼,原始碼字串長度在2000000之內。字串中字元都是ascii碼可見字元(不包括回車)。
output
按以下格式每行乙個,輸出每個病毒出現次數。未出現的病毒不需要輸出。
病毒特徵碼: 出現次數
冒號後有乙個空格,按病毒特徵碼的輸入順序進行輸出。
sample input
3aabb
ccooxxcc%daaaoen....end
struct 結構體當中加乙個
id去點
ncount
,在此單詞的最後乙個結點上賦值為單詞的序號,其他的結點都為0,
inserttrie
函式中多乙個引數單詞的序號
idx,
p->ncount++
改為p->id=idx
。在query
中,訪問的不需要標記,
num陣列記錄字串對應出現的次數
while(temp!=root)
if(temp->id>0)
num[temp->id]++;
temp=temp->fail;
ps:詢問的時候如果匹配串的字元種類多於單詞的,
for(int i=0;i<=len-1;i++)
if(str[i]<'a'||str[i]>'z')
p=root;
continue;
#include#include#include#include#include#include#include#include#include#define inf 0x3f3f3f3f
#define ll long long
using namespace std;
const int maxn=2000010;
int n,m;
sets;
struct trienode
;char strx[1010][60];
char str[maxn];//匹配穿
int num[1010];
void inserttrie(trienode* &root,char* key,int idx)//將字串key放入欄位樹
p=p->next[k];
}p->id=idx;
}void buildfail(trienode *&root)//用bfs建立失配指標
p=p->fail;
}if(!p)
temp->next[i]->fail=root;
}q.push(temp->next[i]);}}
}void query(trienode *&root)
int k=str[i]-'a';
while(!p->next[k]&&p!=root)
p=p->fail;
p=p->next[k];
if(!p)
p=root;
trienode *temp=p;
while(temp!=root)
}for(int i=1;i<=n;i++)
if(num[i]>=1)
cout<>n)
buildfail(root);
gets(str);
query(root);
}return 0;
}
AC自動機模版 字串
ac自動機主要用於解決多模式串的匹配問題 具體指的是 如下圖中 模式串 p中有多個 字串,問這些字串在 主串s的出現的總次數 是字典樹 trie樹 的變種,一種偽樹形結構 主體是樹形的,但是由於加入了失敗指標,使得它變成了乙個有向圖 以當前節點為終點的 模式字串 的數量 int fail 1 fai...
字串 2 AC自動機
ac自動機,其實就是trie樹與kmp的結合,且有dfa 有限狀態機 的性質.理解的關鍵點 1.fail指標 起到回溯作用 2.每次匹配都是主串不動,移動指標now去回溯找字尾的字首 3.乙個優化點,將null指向root 編碼更簡單.考察時一般也會問道dfa的性質.ac自動機解決問題 1.多模式串...
字串應用之AC自動機
ac 自動機的用處 查詢目標串中出現了哪些模式串 即文字字串 s 中出現了哪些字典中的單詞 一種字串上的 dp fail 樹應用 ac 自動機的演算法分三步 構建所有 單詞 的 trie 樹 構建失配指標 模式匹配過程 1.void trie is end now true 2.自動機中乙個節點 p...