算法第四版5-2Tries_Trees
2016-10-11 23:39
281 查看
#include #include #include using namespace std; #define alphabet_size 256 //C++嵌套类 //1.嵌套类的名字只在外围类可见。 //2.类的私有成员只有类的成员和友元可以访问,因此外围类不可以访问嵌套类的私有成员。嵌套类可以访问外围类的成员(通过对象、指针或者引用)。 //3.一个好的嵌套类设计:嵌套类应该设成私有。嵌套类的成员和方法可以设为 public 。 //4.嵌套类可以直接访问外围类的静态成员、类型名( typedef )、枚举值。 class trie { const static int R = alphabet_size; class node { public: int val; node* next[R]; node() { for (int i = 0; i < R; i++) next[i] = NULL; val = NULL; } node(int v) { val = v; for (int i = 0; i < R; i++) next[i] = NULL; } }; node* root; public: trie() { root = NULL; } void put(string s, int v) { root = put(root, s, v, 0); } node* put(node* x, string s, int v, int d) { if (x == NULL) x = new node(); if (d == s.length()) { x->val = v; return x; } char temp = s.at(d); x->next[temp] = put(x->next[(int)temp], s, v, d + 1); return x; } int get(string s) { node* temp = get(root, s, 0); if (temp == NULL) { perror("Invalid"); return NULL; } return temp->val; } node* get(node* x, string s, int d) { if (x == NULL) return NULL; if (d == s.length()) return x; char temp = s.at(d); return get(x->next[temp], s, d + 1); } queue keywithprefix(string pre) { //find all keys that start from p queue res; // use queue to record the key with prefix collect(get(root, pre, 0), pre, res); return res; } void collect(node* x, string p, queue &q) { if (x == NULL) return; //cout << p << endl; //调试递归调用,加栈标识符 if (x->val != NULL) { q.push(p); } for (int i = 0; i < R; i++) { // char 为-128到128,有负值,不能作为index;改用unsigned char或者int,使用(char)转换为char /*if ((int)i == 111||(int)i==101||(int)i==255) { system("pause"); }*/ //cout << (int)i << endl; // 调试循环,输出标识,记录进入函数时的i值 collect(x->next[i], p + (char)i, q); // check everyone but enqueue the certain ones } } queue keythatmatch(string pat) { //find all keys that exactly match pat queue res; collect(root, "", pat, res); return res; } void collect(node* x, string p, string pat, queue &q) { //use p to record the paths if (x == NULL) return; int d = p.length(); //use string length as the signal of end recurrence if (d == pat.length() && x->val != NULL) q.push(p); //all match and the key is valid(x->val!=NULL) if (d == pat.length()) return; //end match or not match for (int i = 0; i < R; i++) { if (pat.at(d) == '.' || i == pat.at(d)) { //单引号为char,双引号为字符串(const char*),结尾有\0 ; string.at(d)为char类型单字符,不能和双引号比较 collect(x->next[i], p + (char)i, pat, q); } } } string longestprefix(string s) { int len = search(root, s, 0, 0); return s.substr(0, len); } // d for the current seacrhing index,len save the length of the matched valid key,not index int search(node* x, string s, int d, int len) { if (x == NULL) return len; if (x->val != NULL) len = d; //in the first recur,d=0,x=root,has 0 letter,so length is 0 //in the second recur,d=1,x=root->next[i],has one letter,if match,length=1 //in the last,eg,d=n,x=last_letter,has all string,so length=n if (d == s.length()) return len; return search(x->next[s.at(d)], s, d + 1, len); //in the last case,d=n-1,s.at[d] refer the last letter(valid),d+1=s.length(),if match,len=s.length() (valid) } void del(string s) { root = del(root, s, 0); } //just set val=NULL,not delete the node ,unless all node->next=NULL node* del(node* x, string s, int d) { if (x == NULL) { perror("valid key"); return root; } if (d == s.length()) x->val = NULL; else { x->next[s.at(d)] = del(x->next[s.at(d)], s, d + 1); //return the deleted node*,if NULL,set next[x] NULL,or update next[x] //assign to x->next[] to update itself,commonly used in recur_delete operation } // !!! if (x->val != NULL) return x; //avoid delete node with same prefix but has value,eg delete shell-1,avoid delete she-5 //prevent delete the prefix has value but no other subtree,it's next array is all NULL excepet the delete one for (int i = 0; i < R; i++) { if (x->next[i] != NULL) return x; //if all next[] is NULL,return NULL,to set pa's next[this]=NULL } return NULL; } }; int main() { int a, n; string s; trie t; queue q; while (true) { cin >> n; while (n--) { cin >> s >> a; t.put(s, a); } cin >> s; cout << t.get(s) << endl; cin >> s; q = t.keywithprefix(s); while (!q.empty()) { cout << q.front() << endl; q.pop(); } cin >> s; q = t.keythatmatch(s); while (!q.empty()) { cout << q.front() << endl; q.pop(); } cin >> s; cout << t.longestprefix(s) << endl; cin >> s; t.del(s); cout << t.longestprefix(s) << endl; } return 0; }
Algorithm 5-2
相关文章推荐
- 算法第四版3-2Binary Search Trees With C++ Implementation
- 算法-第四版-练习1.3.12解答
- 算法第四版 在Linux 中调用Algs4库
- 算法-第四版-练习1.3.26解答
- 算法第四版 coursera公开课 普林斯顿算法 ⅠⅡ部分 Robert Sedgewick主讲《Algorithms》
- 算法第四版 用java实现由中序表达式转换为后续表达式
- 算法第四版学习笔记之快速排序 QuickSort
- 算法-第四版-练习1.3.28解答
- 算法-第四版-练习1.3.12解答
- 算法-第四版-练习1.2.19解答
- 算法-第四版-练习1.2.3解答
- 《算法(第四版)》 1.3.9 补齐左括号
- 算法 第四版 1.3.39 环形缓冲区
- 算法(第四版)下载
- 算法 第四版 1.4.22 仅用加减实现的二分查找
- 算法-第四版-练习1.2.5解答
- 算法-第四版-1.3 背包、队列和栈-习题索引汇总
- 算法 第四版---2.2归并排序
- 算法(第四版) chapter 1.1部分习题答案
- 算法-第四版-练习1.3.13解答