hdu5384 AC自動機模板題,統計模式串在給定串中出現的個數
http://acm.hdu.edu.cn/showproblem.php?pid=5384
Problem Description
Danganronpa is a video game franchise created and developed by Spike Chunsoft, the series' name is compounded from the Japanese words for "bullet" (dangan) and "refutation" (ronpa).
Now, Stilwell is playing this game. There are n verbal evidences, and Stilwell has m "bullets". Stilwell will use these bullets to shoot every verbal evidence.
Verbal evidences will be described as some strings Ai, and bullets are some strings Bj. The damage to verbal evidence Ai from the bullet Bj is f(Ai,Bj).
For example: f(ababa,ab)=2, f(ccccc,cc)=4
Stilwell wants to calculate the total damage of each verbal evidence Ai after shooting all m bullets Bj, in other words is ∑mj=1f(Ai,Bj).
Now, Stilwell is playing this game. There are n verbal evidences, and Stilwell has m "bullets". Stilwell will use these bullets to shoot every verbal evidence.
Verbal evidences will be described as some strings Ai, and bullets are some strings Bj. The damage to verbal evidence Ai from the bullet Bj is f(Ai,Bj).
f(A,B)=∑i=1|A|−|B|+1[ A[i...i+|B|−1]=B ]
In other words, f(A,B) is
equal to the times that string B appears
as a substring in string A.For example: f(ababa,ab)=2, f(ccccc,cc)=4
Stilwell wants to calculate the total damage of each verbal evidence Ai after shooting all m bullets Bj, in other words is ∑mj=1f(Ai,Bj).
Input
The first line of the input contains a single number T,
the number of test cases.
For each test case, the first line contains two integers n, m.
Next n lines, each line contains a string Ai, describing a verbal evidence.
Next m lines, each line contains a string Bj, describing a bullet.
T≤10
For each test case, n,m≤105, 1≤|Ai|,|Bj|≤104, ∑|Ai|≤105, ∑|Bj|≤105
For all test case, ∑|Ai|≤6∗105, ∑|Bj|≤6∗105, Ai and Bj consist of only lowercase English letters
For each test case, the first line contains two integers n, m.
Next n lines, each line contains a string Ai, describing a verbal evidence.
Next m lines, each line contains a string Bj, describing a bullet.
T≤10
For each test case, n,m≤105, 1≤|Ai|,|Bj|≤104, ∑|Ai|≤105, ∑|Bj|≤105
For all test case, ∑|Ai|≤6∗105, ∑|Bj|≤6∗105, Ai and Bj consist of only lowercase English letters
Output
For each test case, output n lines,
each line contains a integer describing the total damage of Ai from
all m bullets, ∑mj=1f(Ai,Bj).
Sample Input
1
5 6
orz
sto
kirigiri
danganronpa
ooooo
o
kyouko
dangan
ronpa
ooooo
ooooo
Sample Output
1
1
0
3
7
/**
hdu5384 AC自動機模板題,統計模式串在給定串中出現的個數
*/
#include<string.h>
#include<algorithm>
#include<iostream>
#include<stdio.h>
#include<queue>
using namespace std;
char str[100010][10010];
int num[100010],n,m;
struct Trie
{
int next[10010*50][28],fail[10010*50],end[10010*50];
int root,L;
int newnode()
{
for(int i=0; i<26; i++)
{
next[L][i]=-1;
}
end[L++]=-1;
return L-1;
}
void init()
{
L=0;
root=newnode();
}
void insert(char *s)
{
int len=strlen(s);
int now=root;
for(int i=0; i<len; i++)
{
if(next[now][s[i]-'a']==-1)
{
next[now][s[i]-'a']=newnode();
}
now=next[now][s[i]-'a'];
}
if(end[now]==-1)///標記模式串出現的次數
{
end[now]=1;
}
else
{
end[now]++;
}
}
void build()
{
queue<int>Q;
fail[root]=root;
for(int i=0; i<26; i++)
{
if(next[root][i]==-1)
{
next[root][i]=root;
}
else
{
fail[next[root][i]]=root;
Q.push(next[root][i]);
}
}
while(!Q.empty())
{
// printf("**\n");
int now=Q.front();
Q.pop();
for(int i=0; i<26; i++)
{
if(next[now][i]==-1)
next[now][i]=next[fail[now]][i];
else
{
fail[next[now][i]]=next[fail[now]][i];
Q.push(next[now][i]);
}
}
}
}
void query(char* s)
{
memset(num,0,sizeof(num));
int len=strlen(s);
int now=root;
for(int i=0; i<len; i++)
{
now=next[now][s[i]-'a'];
int temp=now;
while(temp!=root)
{
if(end[temp]!=-1)///統計所有模式串出現的次數,num陣列在0~m之間定能取到所有end[temp]必不大於m
{
num[end[temp]]+=end[temp];
}
temp=fail[temp];
}
}
int ans=0;
for(int i=0; i<=m; i++)
{
if(num[i]>0)
ans+=num[i];
}
printf("%d\n",ans);
}
} ac;
char s[10005];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(int i=0; i<n; i++)
{
scanf("%s",str[i]);
}
ac.init();
for(int i=0; i<m; i++)
{
scanf("%s",s);
ac.insert(s);
}
ac.build();
//printf("**\n");
for(int i=0; i<n; i++)
{
ac.query(str[i]);
}
}
return 0;
}
相關文章
- hdu2222 AC自動機-給定串中出現了幾個模式串模式
- hdu3065 AC自動機-每個標準串在模式串中出現的次數模式
- hdu2896 AC自動機-標記哪些模式串在目標串中出現過模式
- AC 自動機——多模式串匹配模式
- 編寫一個程式實現模式串的各種模式匹配模式
- abc295D 統計由SS構成的子串個數
- 串的基本運算實現-加密解密串加密解密
- AC自動機+trie樹實現高效多模式匹配字典模式
- 自己實現一個 DFA 串模式識別器(一)模式
- 自己實現一個 DFA 串模式識別器(二)模式
- LeetCode題解(1639):統計只差一個字元的子串數目(Python)LeetCode字元Python
- 深度學習與計算機視覺系列(9)_串一串神經網路之動手實現小例子深度學習計算機視覺神經網路
- js如何計算一個字元在字串中出現的次數JS字元字串
- 2022-07-11:給定n位長的數字字串和正數k,求該子符串能被k整除的子串個數。 (n<=1000,k<=100)字串
- 變數子串的常用操作變數
- 【閒談】如何統計字串中出現最多的字母與個數字串
- 2017年阿里線上程式設計題-- 數串分組阿里程式設計
- (迴文串)leetcode各種迴文串問題LeetCode
- AC自動機:Tire樹+KMPKMP
- 串聯諧振在各個領域的應用
- 動態規劃題:把一個字串變為迴文串動態規劃字串
- 統計檔案中出現的單詞次數
- 【通過操作指標,與指標做函式引數'實現字串在主串中出現的次數,然後將出現的部分依照要求進行替換 】...指標函式字串
- Aho-Corasick 演算法 AC自動機實現演算法
- 計算兩個字串最大公有子串字串
- AC自動機學習筆記筆記
- 【Ac自動機】hdu 5880 Family ViewView
- 串(2)--模式匹配演算法模式演算法
- 【練習】串的堆分配實現
- 【練習】塊鏈串的實現
- 串的堆分配表示與實現
- 假設串S1 = "I come from Beijing",S2 = "Chongqing" ,Sub = "America". 利用串的基本操作,如果串的賦值、串的插入、串的刪除、串的替換、對上面賦值
- POJ 3294 Life Forms(字尾陣列求k個串的最長子串)ORM陣列
- 我也統計一下字串中出現最多的字母與個數字串
- 子串查詢;及排列子串分析
- 【演算法拾遺】阿里實習生電面題目:輸出給定字串的全部連續子串演算法阿里字串
- 順序結構儲存串實現串萬用字元匹配的演算法字元演算法
- 基於Python+requests搭建的自動化框架-實現流程化的介面串聯Python框架