标签:pointer ann 检索 node ref remove tle can cout
这是一个Trie树标准模版
By Leo
本人版权,请勿抄袭!!
先看教程:
1. 什么是trie树
例如,电子英文词典,为了方便用户快速检索英语单词,可以建立一棵trie树。例如词典由下面的单词成:a、b、c、aa、ab、ac、ba、ca、aba、abc、baa、bab、bac、cab、abba、baba、caba、abaca、caaba
再举一个例子。给出一组单词,inn, int, at, age, adv, ant, 我们可以得到下面的Trie:
可以看出:
查询操纵非常简单。比如要查找int,顺着路径i -> in -> int就找到了。
对于一个单词,从根开始,沿着单词的各个字母所对应的树中的节点分支向下走,直到单词遍历完,将最后的节点标记为红色,表示该单词已插入trie树。
其方法为:
(1) 从根结点开始一次搜索;
(2) 取得要查找关键词的第一个字母,并根据该字母选择对应的子树并转到该子树继续进行检索;
即从根开始按照单词的字母顺序向下遍历trie树,一旦发现某个节点标记不存在或者单词遍历完成而最后的节点未标记为红色,则表示该单词不存在,若最后的节点标记为红色,表示该单词存在。如下图中:trie树中存在的就是abc、d、da、dda四个单词。在实际的问题中可以将标记颜色的标志位改为数量count等其他符合题目要求的变量。
代码上有英文注释,请还是不懂的人看一看。。
再看不懂,本人也无能为力了~~~
代码:
/** * Leolee 2017(C) * Trie.cpp * This is a standard Trie‘s template by Leolee * The program has its copyright and you cannot copy it * before the author allowed. */ //Define the TRIE Template here #ifndef _TRIE_ #define _TRIE_ #include <iostream> //The standard IO stream #include <sstream> //The standard String library and string stream #include <cstring> //The C-style string library #include <cassert> //The C-style assert library #include <climits> //For using "INT_MIN" #define MAXNUM 26 //The max num of the children of a node using namespace std; //using the standard namespace "std" //define the Trie node here struct Trie_Node { string word;//The word int count; //The number of occurrences of a word Trie_Node *Next_Branch[MAXNUM];//Pointer to a 26-character node Trie_Node() : count(0) { word.empty(); memset(Next_Branch, NULL, sizeof(Trie_Node*) * MAXNUM); } ~Trie_Node() {}; }; class Trie { private: Trie_Node* ROOT; private: void Reset(Trie_Node* Root); //Reset The trie tree void Print(Trie_Node* Root); public: void Insert(string str); //Insert the string str bool Search(string str, int& cnt); //Find the string str and return the number of occurrences bool Remove(string str); //Delete the string str void PrintALL(); //Prints all the nodes in the trie tree bool PrintPre(string str); //Print a word prefixed with str Trie() { ROOT = new Trie_Node(); //Note that the root of the dictionary tree does not hold characters }; ~Trie() { Reset(ROOT); }; }; #endif //_TRIE_ //Insert a word void Trie::Insert(string str) { if (str.empty()) return; Trie_Node *NODE = ROOT; int len = str.size(); for (int i = 0;i < len;i++) { int index = str.at(i) - ‘a‘; //Case sensitive if (index < 0 || index > MAXNUM)//No insertion is performed return; if (NODE->Next_Branch[index] == NULL) //The prefix of the word does not exist and is to be generated for that node NODE->Next_Branch[index] = new Trie_Node(); NODE = NODE->Next_Branch[index]; //Go to the next node } if (!NODE->word.empty()) //The word has already appeared { NODE->count++; return; } else //The word did not appear, and we should insert it { NODE->count++; NODE->word = str; } } //Find a word, if it appeared, then return the number of occurrences of the word. //If not, it will return false bool Trie::Search(string str, int& cnt) { assert(!str.empty()); int index = INT_MIN; Trie_Node *NODE = ROOT; int length = str.size(); int i = 0; while (NODE && i < length) { index = str.at(i) - ‘a‘; //Case sensitive if (index < 0 || index > MAXNUM) //No insertion is performed return false; NODE = NODE->Next_Branch[index]; i++; } if (NODE && !NODE->word.empty()) { cnt = NODE->count; return true; } return false; } bool Trie::Remove(string str) { assert(!str.empty()); int index = INT_MIN; Trie_Node *NODE = ROOT; int length = str.size(); int i = 0; while (NODE && i < length) { index = str.at(i) - ‘a‘; //Case sensitive if (index < 0 || index > MAXNUM) //No deletion is performed return false; NODE = NODE->Next_Branch[index]; i++; } if (NODE && !NODE->word.empty()) { NODE->word.clear(); return true; } } void Trie::PrintALL() { Print(ROOT); } bool Trie::PrintPre(string str) { assert(!str.empty()); int index = INT_MIN; Trie_Node *NODE = ROOT; int length = str.size(); int i = 0; while (NODE && i < length) { index = str.at(i) - ‘a‘; //Case sensitive if (index < 0 || index > MAXNUM) return false; NODE = NODE->Next_Branch[index]; i++; } if (NODE) //We can find the word { Print(NODE); return true; } return false; } void Trie::Print(Trie_Node* Root) { if (Root == NULL) return; //Print the word if (!Root->word.empty()) cout << Root->word << " " << Root->count << endl; for (int i = 0;i < MAXNUM;i++) Print(Root->Next_Branch[i]);//Print all the children of the node } //Rest trie tree void Trie::Reset(Trie_Node* Root) { if (Root == NULL) return; for (int i = 0;i < MAXNUM;i++) Reset(Root->Next_Branch[i]); //Reset the word if (!Root->word.empty()) Root->word.clear(); delete Root; //Delete the node Root = NULL; } int NUM_TO_INSERT, NUM_TO_SEARCH, NUM_TO_DELETE, NUM_TO_SBF; //Main Function int main(int argc, char **argv) { ios::sync_with_stdio(false); Trie TREE; cout << "Input the number of words you want to insert:" << endl; cin >> NUM_TO_INSERT; for (int i = 0;i < NUM_TO_INSERT;i++) { string STRING; cin >> STRING; TREE.Insert(STRING); } cout << endl; cout << "Input the number of words you want to search:" << endl; cin >> NUM_TO_SEARCH; for (int i = 0;i < NUM_TO_SEARCH;i++) { string STRING; cin >> STRING; int count = -1; bool CanFind = TREE.Search(STRING, count); if (CanFind) cout << STRING << " exists, its number of occurrences is " << count << endl; else cout << STRING << " does not exists!" << endl; } cout << endl; cout << "Here are all the nodes in the Trie tree:" << endl; TREE.PrintALL(); cout << endl; cout << "Input the number of words you want to delete:" << endl; cin >> NUM_TO_DELETE; for (int i = 0;i < NUM_TO_DELETE;i++) { string STRING; cin >> STRING; bool Is_Deleted = TREE.Remove(STRING); if (Is_Deleted) cout << STRING << " deleted!" << endl; else cout << "Failed to delete " << STRING << endl; } cout << endl; cout << "Input the number of words you want to search by prefix:" << endl; cin >> NUM_TO_SBF; for (int i = 0;i < NUM_TO_SBF;i++) { string STRING; cin >> STRING; bool STATUS = TREE.PrintPre(STRING); if (!STATUS) cout << "There aren‘t any words begin with " << STRING << " !"; cout << endl; } cout << endl; return 0; }
标签:pointer ann 检索 node ref remove tle can cout
原文地址:http://www.cnblogs.com/Leoleepz/p/6349748.html