字典树模板
2017-07-18 14:58
246 查看
通过学习别的高手代码,我总结出一个比较实用的字典树增删查的模板
用2000000*26左右的数组存储单词字母顺序。中间记录的都是位置关系。
用2000000*26左右的数组存储单词字母顺序。中间记录的都是位置关系。
#include<cstdio> #include<string> #include<map> #include<cstring> #include<algorithm> #define maxn 50 using namespace std; typedef long long LL; const int maxp=2064888; char s[maxn], x[maxn]; int n, tot, cnt[maxp]; int f[maxp][26]; int main() { tot = 1; cnt[1] = 0; memset(f[0], 0, sizeof(f[0])); while (~scanf("%s%s", s, x)) { if (s[0] == 'i')//增添一个单词 { int rt = 1; for (int i = 0,j; x[i]; i++) { j = x[i] - 'a'; if (!f[rt][j]) { f[rt][j] = ++tot;//发现是新单词,则改变该位置的指向,tot就是记录 cnt[tot] = 0;//记录那一行没有使用 memset(f[tot], 0, sizeof(f[tot]));//为指向的一行清理空间 } rt = f[rt][j];//如果在这个位置已经有字母了,就移动到他指向的位置 ++cnt[rt];//标记此行用过 } } if (s[0] == 's')//查找前缀,是否存在 { int rt = 1; for (int i = 0, j; x[i]; i++) { j = x[i] - 'a'; if (!(rt = f[rt][j])) { printf("No\n"); rt = 0; break; } } if (rt) printf("Yes\n"); } /* for(int j=1; j<22; j++) { printf("\n"); for(int i=0; i<26; i++) { if(f[j][i]==0) printf("."); else printf("%d ",f[j][i]); } } */ if (s[0] == 'd')//删除拥有该前缀的所有单词 { int rt = 1; for (int i = 0, j; x[i]; i++) { j = x[i] - 'a'; if (!f[rt][j]) { rt = 0; break; } else rt = f[rt][j]; } if (!rt) continue; int tr = 1; for (int i = 0, j; x[i]; i++) { j = x[i] - 'a'; if (!f[j]) break; else { int k = f [j]; cnt[k] -= cnt[rt]; if (!cnt[k]) k = f [j] = 0; tr = k; } } } } return 0; } 相关文章推荐