constint N = 100010; int son[N][26], cnt[N], idx; char str[N]; // son[N]用来存树里的结点 ---> 静态链表 // son[N][26]用来表示结点的键值(26个小写字母) // cnt[N]用来统计单词出现次数 // idx和静态链表中的idx一样,用来表示当前操作的是第几个结点
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]; } // 循环结束后,p就是这个单词的最后一个字母所在结点 cnt[p]++; // 单词出现次数 }
intquery(char* str){ int p = 0; for (int i = 0; str[i]; i++) { int u = str[i] - 'a'; if (!son[p][u]) return0; // 如果想要查找的路径上有结点不存在,说明该单词不存在 p = son[p][u]; } return cnt[p]; }