voidinsert() { int root = 0; for (int i = 0; str[i]; i ++) { int s = str[i] - 'a'; if(!son[root][s]) son[root][s] = ++ idx; root = son[root][s]; } cnt[root]++; }
root 节点设为0。son{ root }{ s }表示root这个节点上的s的编号idx。倘若这个点没有被创建,那就 son{ root }{ s } = ++ idx; 感觉这个 root 有并查集那味儿。存储他儿子的编号,便于查找。这时候就有读者要问,这个cnt{ N }是干嘛用的呢?答案是记录以这个点为结尾的数量。在搜前缀时,不一定只有一个字符从这里结束,所以要记录一下数量。
搜索
1 2 3 4 5 6 7 8 9 10 11 12
intsearch() { int root = 0, res = 0; for(int i = 0; str[i]; i ++) { int s = str[i] - 'a'; if(!son[root][s]) break; root = son[root][s]; res += cnt[root]; } return res; }