字典树Trie树的应用

论坛 期权论坛 编程之家     
选择匿名的用户   2021-5-31 08:25   610   0

问题:有若干个字符串,求他们的最长公共前缀子串。

解法:该问题的一个比较好的办法是使用Trie树。因为Trie树有明显的字符串前缀特征。在查询近似前缀的时候经常用到。这里我建立了Trie树,且为了寻找最长公共前缀子串更方便,对结点加入了分支个数属性branch和出现次数属性times。这样,把所有字符串加入Trie树之后,通过根结点出发寻找单分支路径且出现次数均为字符串集个数,就可以找到结果。


代码:

  1. #include <string>
  2. #include <iostream>
  3. #include <vector>
  4. #include <malloc.h>
  5. using namespace std;
  6. #define N 26
  7. typedef struct node {
  8. char ch;
  9. int branch ; //记录分支树,方便最后查询
  10. int times;
  11. node* child[N];
  12. }node, *Trie;
  13. Trie init_Trie()
  14. {
  15. Trie root = (node*)malloc(sizeof(node)); //Trie树的根节点不存储数据
  16. root->branch = 0;
  17. root->times = 0;
  18. for(int i=0;i<N;i++)
  19. root->child[i] = NULL;
  20. return root;
  21. }
  22. void insert_Trie(Trie root, const string str)
  23. {
  24. int n = str.length();
  25. if(n == 0)
  26. {
  27. root->times ++;
  28. return;
  29. }
  30. int i=0;
  31. int idx;
  32. node *p = root;
  33. root->times++;
  34. while(i<n)
  35. {
  36. idx = str[i] - 'a';
  37. if(p->child[idx] != NULL)
  38. {
  39. p = p->child[idx];
  40. p->times ++;
  41. i++;
  42. }
  43. else
  44. {
  45. node* tmp = (node*)malloc(sizeof(node));
  46. tmp->ch = str[i];
  47. tmp->branch = 0;
  48. tmp->times = 1;
  49. for(int j=0;j<N;j++)
  50. tmp->child[j] = NULL;
  51. p->branch ++;
  52. p->child[idx] = tmp;
  53. p = tmp;
  54. i++;
  55. }
  56. }
  57. }
  58. string longestCommonPrefix(vector<string> &strs)
  59. {
  60. int n = strs.size();
  61. if(n == 0)
  62. return "";
  63. int i;
  64. Trie root = init_Trie();
  65. for(i=0;i<n;i++)
  66. insert_Trie(root, strs[i]);
  67. i = 0;
  68. node* p = root;
  69. while(i<strs[0].length() && p->branch == 1 && p->times == n)
  70. {
  71. p = p->child[strs[0][i] - 'a'];
  72. i++;
  73. }
  74. if(p->times < n)
  75. i--;
  76. return strs[0].substr(0,i);
  77. }
  78. int main()
  79. {
  80. vector<string> strs;
  81. strs.push_back("a");
  82. strs.push_back("aa");
  83. //strs.push_back("abcd");
  84. string result = longestCommonPrefix(strs);
  85. cout<<result<<endl;
  86. return 1;
  87. }
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP