字典树(Trie,前缀树)CSU 1115: 最短的名字

举报
用户已注销 发表于 2021/11/19 01:51:58 2021/11/19
【摘要】 目录 一,字典树 二,OJ实战 CSU 1115: 最短的名字 HDU - 1075 What Are You Talking About (map或字典树) 一,字典树 字典树,又称前缀树。 前缀树的3个基本性质: 根节点不包含字符,除根节点外每一个节点都只包含一个字符。从根节点到某一节点,路径上经过的字符连接起来,...

目录

一,字典树

二,OJ实战

CSU 1115: 最短的名字

HDU - 1075 What Are You Talking About (map或字典树)


一,字典树

字典树,又称前缀树。

前缀树的3个基本性质:

  • 根节点不包含字符,除根节点外每一个节点都只包含一个字符。
  • 从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串。
  • 每个节点的所有子节点包含的字符都不相同。

trie1

如图,没画出来的代表空指针。

节点11对应的字符串金山aba,节点15对应的字符串就是caaa

应用场景:存储大量字符串并频繁查找

 

二,OJ实战

CSU 1115: 最短的名字

题目:

Description

在一个奇怪的村子中,很多人的名字都很长,比如aaaaa, bbb and abababab。

名字这么长,叫全名显然起来很不方便。所以村民之间一般只叫名字的前缀。比如叫'aaaaa'的时候可以只叫'aaa',因为没有第二个人名字的前三个字母是'aaa'。不过你不能叫'a',因为有两个人的名字都以'a'开头。村里的人都很聪明,他们总是用最短的称呼叫人。输入保证村里不会有一个人的名字是另外一个人名字的前缀(作为推论,任意两个人的名字都不会相同)。

如果村里的某个人要叫所有人的名字(包括他自己),他一共会说多少个字母?

Input

输入第一行为数据组数T (T<=10)。每组数据第一行为一个整数n(1<=n<=1000),即村里的人数。以下n行每行为一个人的名字(仅有小写字母组成)。输入保证一个村里所有人名字的长度之和不超过1,000,000。

Output

对于每组数据,输出所有人名字的字母总数。

Sample Input

1
3
aaaaa
bbb
abababab

Sample Output

5

 

思路:字典树

ans[i][j]表示第i个节点的第j个孩子的编号,j>0

ans[i][0]表示第i个节点的所有后代中叶子节点的个数

代码:


  
  1. #include<iostream>
  2. #include<string>
  3. using namespace std;
  4. const int m = 500000;
  5. int ans[m][27], key = 0;
  6. int f(int k)
  7. {
  8. if (ans[k][0] == 1)return 1;
  9. int r = ans[k][0];
  10. for (int i = 1; i <= 26; i++)
  11. if (ans[k][i])r += f(ans[k][i]);
  12. return r;
  13. }
  14. int main()
  15. {
  16. int T,n;
  17. string s;
  18. cin >> T;
  19. while (T--)
  20. {
  21. cin >> n;
  22. memset(ans[0], 0, sizeof(ans[0]));
  23. while (n--)
  24. {
  25. cin >> s;
  26. for (int i = 0,j=0; s[i]; i++)
  27. {
  28. if (ans[j][s[i] - 'a' + 1] == 0)
  29. {
  30. ans[j][s[i] - 'a' + 1] = ++key;
  31. memset(ans[key], 0, sizeof(ans[key]));
  32. }
  33. ans[j][0]++;
  34. j = ans[j][s[i] - 'a' + 1];
  35. }
  36. }
  37. cout << f(0) - ans[0][0] << endl;
  38. }
  39. return 0;
  40. }

HDU - 1075 What Are You Talking About (map或字典树)

Ignatius is so lucky that he met a Martian yesterday. But he didn't know the language the Martians use. The Martian gives him a history book of Mars and a dictionary when it leaves. Now Ignatius want to translate the history book into English. Can you help him?

Input

The problem has only one test case, the test case consists of two parts, the dictionary part and the book part. The dictionary part starts with a single line contains a string "START", this string should be ignored, then some lines follow, each line contains two strings, the first one is a word in English, the second one is the corresponding word in Martian's language. A line with a single string "END" indicates the end of the directory part, and this string should be ignored. The book part starts with a single line contains a string "START", this string should be ignored, then an article written in Martian's language. You should translate the article into English with the dictionary. If you find the word in the dictionary you should translate it and write the new word into your translation, if you can't find the word in the dictionary you do not have to translate it, and just copy the old word to your translation. Space(' '), tab('\t'), enter('\n') and all the punctuation should not be translated. A line with a single string "END" indicates the end of the book part, and that's also the end of the input. All the words are in the lowercase, and each word will contain at most 10 characters, and each line will contain at most 3000 characters.

Output

In this problem, you have to output the translation of the history book.

Sample Input


  
  1. START
  2. from fiwo
  3. hello difh
  4. mars riwosf
  5. earth fnnvk
  6. like fiiwj
  7. END
  8. START
  9. difh, i'm fiwo riwosf.
  10. i fiiwj fnnvk!
  11. END

Sample Output


  
  1. hello, i'm from mars.
  2. i like earth!

AC代码一(Map实现):


  
  1. #include <iostream>
  2. #include<string>
  3. #include<map>
  4. using namespace std;
  5. int main()
  6. {
  7. string a, b;
  8. char *ch = new char[3005], *p;
  9. map<string, string>m;
  10. m.clear();
  11. cin >> a;
  12. while (cin >> a >> b)
  13. {
  14. if (a[0] == 'E')break;
  15. m[b] = a;
  16. }
  17. cin.get();
  18. while (cin.getline(ch,3005))
  19. {
  20. p = ch;
  21. if (ch[0] == 'E')break;
  22. while (ch[0] != '\0')
  23. {
  24. b = "";
  25. while (ch[0] >= 'a' && ch[0] <= 'z')b += ch[0], ch++;
  26. if (m.find(b) == m.end())cout << b;
  27. else cout << m[b];
  28. while (ch[0] != '\0' && ch[0] < 'a' || ch[0] > 'z')
  29. {
  30. cout << ch[0];
  31. ch++;
  32. }
  33. }
  34. cout << endl;
  35. ch = p;
  36. }
  37. return 0;
  38. }

AC代码二(字典树实现):


  
  1. #include <iostream>
  2. #include<string>
  3. #include<string.h>
  4. using namespace std;
  5. string a[1000000], b;
  6. const int m = 5000000;
  7. int ans[m][27], key = 0, ka = 0;
  8. void insert(string s)
  9. {
  10. int i,j;
  11. for (i = 0, j = 0; s[i]; i++)
  12. {
  13. if (ans[j][s[i] - 'a' + 1] == 0)
  14. {
  15. ans[j][s[i] - 'a' + 1] = ++key;
  16. memset(ans[key], 0, sizeof(ans[key]));
  17. }
  18. j = ans[j][s[i] - 'a' + 1];
  19. }
  20. ans[j][0] = ka;
  21. }
  22. int find(string s)
  23. {
  24. int i, j;
  25. for (i = 0, j = 0; s[i]; i++)
  26. {
  27. if (ans[j][s[i] - 'a' + 1] == 0)return 0;
  28. j = ans[j][s[i] - 'a' + 1];
  29. }
  30. return ans[j][0];
  31. }
  32. int main()
  33. {
  34. char *ch = new char[3005], *p;
  35. cin >> b;
  36. memset(ans[0], 0, sizeof(ans[0]));
  37. while (cin >> a[++ka] >> b)
  38. {
  39. if (a[ka][0] == 'E')break;
  40. insert(b);
  41. }
  42. cin.get();
  43. while (cin.getline(ch,3005))
  44. {
  45. p = ch;
  46. if (ch[0] == 'E')break;
  47. while (ch[0] != '\0')
  48. {
  49. b = "";
  50. while (ch[0] >= 'a' && ch[0] <= 'z')b += ch[0], ch++;
  51. if (find(b) ==0)cout << b;
  52. else cout << a[find(b)];
  53. while (ch[0] != '\0' && ch[0] < 'a' || ch[0] > 'z')
  54. {
  55. cout << ch[0];
  56. ch++;
  57. }
  58. }
  59. cout << endl;
  60. ch = p;
  61. }
  62. return 0;
  63. }

PS:a数组不能开小了,10万是不够的,100万是够的。

 

文章来源: blog.csdn.net,作者:csuzhucong,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/nameofcsdn/article/details/112343283

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。