給定N個字符串S1,S2...SN,接下來進行M次詢問,每次詢問給定一個字符串T,求S1~SN中有多少個字符串是T的前綴。輸入字符串的總長度不超過10^6,僅包含小寫字母。ios
第一行兩個整數N,M。接下來N行每行一個字符串Si。接下來M行每行一個字符串表示詢問。spa
對於每一個詢問,輸出一個整數表示答案code
3 2
ab
bc
abc
abc
efgblog
2
0字符串
trie樹操做,把這n個字符串插入到trie中,並更新一下節點信息
在這道題中,每一個節點只須要保存cnt表示當前節點是多少個字符串的末尾節點,那麼若是被詢問的字符串T匹配到當前節點,表示從T的首字符開始到當前一直是匹配的,那麼咱們在查詢過程當中累加節點的cnt值就能夠了
中間注意判斷一下,若是trie已經搜到了葉子節點還要但匹配尚未完成,直接return ansget
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #define Min(a,b) (a)<(b)?(a):(b) #define Max(a,b) (a)>(b)?(a):(b) #define in(i) (i=read()) using namespace std; int read() { int ans=0,f=1; char i=getchar(); while(i<'0' || i>'9') {if(i=='-') f=-1; i=getchar();} while(i>='0' && i<='9') {ans=(ans<<1)+(ans<<3)+i-'0'; i=getchar();} return ans*f; } int n,m,tot; int trie[1000010][27],cnt[1000010]; void insert(char* str) { int len=strlen(str),p=0; for(int i=0;i<len;i++) { int ch=str[i]-'a'; if(!trie[p][ch]) trie[p][ch]=++tot; p=trie[p][ch]; } cnt[p]++; } int search(char* str) { int ans=0; int len=strlen(str),p=0; for(int i=0;i<len;i++) { int ch=str[i]-'a'; p=trie[p][ch]; if(!p) return ans; ans+=cnt[p]; } return ans; } int main() { char s[1000010]; in(n); in(m); for(int i=1;i<=n;i++) { scanf("%s",s); insert(s); } for(int i=1;i<=m;i++) { scanf("%s",s); printf("%d\n",search(s)); } return 0; }