相关内容
字典树(TrieTree),又称单词查找树或键树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:最大限度地减少无谓的字符串比较,查询效率比哈希表高
TrieTree 的核心思想是空间换时间。利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的
基本性质:
- 根节点不包含字符,除根节点外每一个节点都只包含一个字符
- 从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串
- 每个节点的所有子节点包含的字符都不相同
基本要求:
- 给定一篇英文文章,构建 TrieTree
- 在 TrieTree 上检索单词是否存在以及出现频率
这是以前做数据结构的课程设计作业,今天翻电脑偶然看到的,做一下记录
代码
结点类代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| class Node { Node* next[26];
int count;
Node(): count(0) { for (int i = 0; i < 26; i++) next[i] = nullptr;
}
friend class TrieTree; };
|
字典树存在根结点,从根结点开始,有 26 个 Node 型指针,分别代表 26 个英文字母。如果字母存在,则对应的指针指向一个动态建立的 Node 型结点
一开始构建字典树时,在 Node 中还创建了 char 型变量 letter,用来记录对应字母。但是可以用指针是否指向存在的结点来判断这个字母是不是存在
如果单词插入成功,则结尾字母对应的结点上的 int 型变量 count 从 0 为 1,表示从根结点到此结点,一路上的字母组成了某一个单词,同时 count 变量还可以作为单词存储次数的计数器
调用代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
| class TrieTree { public: TrieTree(string str);
void Insertion(string str);
bool Query(string str); private: Node* root; };
TrieTree::TrieTree(string str) { start = clock();
this->root = new Node();
string str2; char s[26]; int length = 0; int len = 0;
while (1) { while (isalpha(str[length])) s[len++] = str[length++]; s[len] = '\0'; str2 = s; Insertion(str2); if (str[length] == '\0') break; len = 0; while (isalpha(str[length]) == 0) length++; }
stop = clock(); tree_Duration = float((stop - start) * 1000) / CLOCKS_PER_SEC; cout << "字典树构建成功,构建时间为" << tree_Duration << "毫秒" << endl; cout << "字典树内容为:" << endl; cout << str; }
void TrieTree::Insertion(string str) { Node* ptr = this->root; int num = 0; for (int len = 0; len != str.length(); len++) { if (str[len] >= 'A' && str[len] <= 'Z') num = str[len] - 'A'; else num = str[len] - 'a'; if (ptr->next[num] == nullptr) ptr->next[num] = new Node; ptr = ptr->next[num]; } ptr->count++; }
bool TrieTree::Query(string str) { start = clock();
Node* ptr = root; int num = 0; bool judge = true;
for (int len = 0; len != str.length(); len++) { if (isupper(str[len])) str[len] = tolower(str[len]);
num = str[len] - 'a'; if (ptr->next[num] == nullptr) { judge = false; break; } else ptr = ptr->next[num]; } if (ptr->count == 0) judge = false;
stop = clock(); tree_Duration = float((stop - start) * 1000) / CLOCKS_PER_SEC;
if (judge) cout << str << "检索成功,共出现" << ptr->count << "次,检索时间为" << tree_Duration << "毫秒" << endl; else cout << str << "检索失败,检索时间为" << tree_Duration << "毫秒" << endl; return judge; }
|