voidinsert(char str[]) { int p = 0; for (int i = 0; str[i]; i ++ ) { int u = str[i] - 'a'; if (!son[p][u]) son[p][u] = ++ idx; p = son[p][u]; } cnt[p] ++ ; }
intquery(char str[]) { int p = 0; int ans = 0; for (int i = 0; str[i]; i ++ ) { int u = str[i] - 'a'; ans += cnt[p]; if (!son[p][u]) return ans; p = son[p][u]; } ans += cnt[p]; return ans; }
三、代码
#include<iostream>
usingnamespace std;
constint N = 1000010, M = 26; // 全为小写字母M=26
int n, m; int son[N][M], cnt[N], idx; // idx相当于每个节点的身份证号(大于0)
voidinsert(char str[]) { int p = 0; // 始终指向当前节点,始终判断儿子节点 for (int i = 0; str[i]; i ++ ) { int u = str[i] - 'a'; if (!son[p][u]) son[p][u] = ++ idx; // 赋予当前节点的儿子节点身份 p = son[p][u]; // 继续看儿子节点 } cnt[p] ++ ; // 以编号p为结尾的字符串个数 }
intquery(char str[]) { int p = 0; int ans = 0; for (int i = 0; str[i]; i ++ ) { int u = str[i] - 'a'; ans += cnt[p]; if (!son[p][u]) return ans; p = son[p][u]; } ans += cnt[p]; return ans; }
intmain() { cin >> n >> m; while ( n -- ) { char str[N]; cin >> str; insert(str); } while ( m -- ) { char str[N]; cin >> str; cout << query(str) << endl; } return0; }