程序员面试金典——解题总结: 9.18高难度题 18.8---拓展: 实现一个Trie树
2017-01-19 19:02
477 查看
#include <iostream> #include <stdio.h> #include <string> #include <vector> using namespace std; /* 问题:请实现一个trie树,并执行查找。 首先实现trie树:trie树,本质上是一颗多叉树,每个结点是一个字符,如果在某个结点处对应的标记说从根节点到当前结点组成的内容是一个字符串, 就表明找到了一个字符串。本质是将一个字符串的各个字符作为结点插入到树中。 输入: 10(字符串数组中元素个数n) cao(待查找字符串) cai cao li lan cha chang wen chao yun yang 10(字符串数组中元素个数n) ca cai cao li lan cha chang wen chao yun yang 输出: yes(能够查找到,不能查找到输出no) no */ //前缀树结点包含:孩子结点指针数组,从根节点到当前结点是否是一个字符串的标记【结点的字符,体现在孩子结点指针数组的下标上,下标index = 字符 - 'a'】 const int BRANCH_NUM = 26;//26个英文字符 class TrieNode { public: TrieNode() { _isString = false; memset(_childs , NULL , sizeof(_childs) ); } bool _isString; TrieNode* _childs[BRANCH_NUM]; }; //前缀树包含了:根节点,查找,删除,销毁等成员和函数 class TrieTree { public: TrieTree(){} ~TrieTree() { deleteTrie(_root); } //插入一个字符串:遍历每个字符,插入到对应子树上,当所有字符处理玩,这只最后一个字符对应结点的字符串标记为真 void insert(char* str) { if(NULL == str || NULL == _root) { return; } TrieNode* curNode = _root; while( (*str) != '\0') { //找到对应子树 int index = (*str) - 'a'; if(index < 0 || index >= BRANCH_NUM) { continue; } //寻找对应子树,如果为空,就新建子树对应结点 TrieNode* childNode = curNode->_childs[index]; if(NULL == childNode) { TrieNode* node = new TrieNode(); curNode->_childs[index] = node; } str++; //设置当前结点继续往下走 curNode = curNode->_childs[index]; } //处理完成后,设置最后结点对应的字符串标记为真 curNode->_isString = true; } //查找某个字符串:对每个字符继续向下遍历对应的结点,直到字符串为空时,此时如果最后一个字符对应的结点的字符串标记如果为真,就说明查找到 bool search(char* str) { if(NULL == str || NULL == _root ) { return false; } TrieNode* curNode = _root; while( (*str) != '\0') { int index = (*str) - 'a'; if(index < 0 || index >= BRANCH_NUM) { continue; } //寻找对应子树,如果为空,就说明没有找到 TrieNode* childNode = curNode->_childs[index]; if(NULL == childNode) { return false; } str++; curNode = childNode; } return curNode->_isString; } //删除树,递归删除:先递归,最后删除结点 void deleteTrie(TrieNode* root) { if(NULL == root) { return; } for(int i = 0 ; i < BRANCH_NUM ; i++ ) { if( root->_childs[i] != NULL ) { deleteTrie(root->_childs[i]); } } delete root; root = NULL; } TrieNode* _root; }; void process() { int strNum; string searchStr; string str; while(cin >> strNum >> searchStr) { //scanf("%s" , searchStr); TrieTree trieTree; TrieNode* root = new TrieNode(); trieTree._root = root; for(int i = 0 ; i < strNum ; i++) { //memset(str , NULL , sizeof(str)); //scanf("%s" , str); cin >> str; //每输入一个字符串,就插入到前缀树中 trieTree.insert((char*)str.data()); } //接下来执行咋找 bool isFind = trieTree.search((char*)searchStr.c_str()); if(isFind) { cout << "yes" << endl; } else { cout << "no" << endl; } } } int main(int argc , char* argv[]) { process(); getchar(); return 0; }
相关文章推荐
- 程序员面试金典——解题总结: 9.18高难度题 18.8给定一个字符串s和一个包含较短字符串的数组T,设计一个方法,根据T中的每一个较短字符串,对s进行搜索
- 程序员面试金典——解题总结: 9.18高难度题 18.10给定两个字典里的单词,长度相等。编写一个方法,将一个单词变换成另一个单词,一次只改动一个字母。
- 程序员面试金典——解题总结: 9.18高难度题 18.4编写一个方法,数出0到n(含)中数字2出现了几次
- 程序员面试金典——解题总结: 9.18高难度题 18.12给定一个正整数和负整数组成的N*M矩阵,编写代码找出元素总和最大的子矩阵。
- 程序员面试金典——解题总结: 9.18高难度题 18.6设计一个算法,给定10亿数字,找出最小的100万个数字。假定计算机内存足以容纳全部10亿个数字。
- 程序员面试金典——解题总结: 9.18高难度题 18.3编写一个方法,从大小为n的数组中随机选出m个整数。要求每个元素被选中的概率相同。
- 程序员面试金典——解题总结: 9.18高难度题 18.1编写一个函数,将两个数字相加。不得使用+或其他算术运算符。
- 程序员面试金典——解题总结: 9.18高难度题 18.2编写一个方法,洗一副牌。要求做到完美洗牌,换言之,这副牌52!种排列组合出现的概率相同
- 程序员面试金典——解题总结: 9.18高难度题 18.7给定一组单词,编写一个程序,找出其中的最长单词,且该单词由这组单词中的其他单词组合而成。
- 程序员面试金典——解题总结: 9.18高难度题 18.9随机生成一些数字并传入某个方法。编写一个程序,每当收到新数字时,找出并记录中位数。
- 程序员面试金典——解题总结: 9.18高难度题 18.13给定一份几百万个单词的清单,设计一个算法,创建由字母组成的最大矩形
- 程序员面试金典——解题总结: 9.18高难度题 18.11给定一个方阵,其中每个单元(像素)非黑即白。设计一个算法,找出四条边都是黑色像素的最大子方阵。
- 程序员面试金典——解题总结: 9.17中等难题 17.11给定rand5(),实现一个方法rand7()。也就是,给定一个产生0到4(含)随机数的方法,编写一个产生0到6(含)随机数的方法
- 程序员面试金典——解题总结: 9.18高难度题 18.5有个内含单词的超大文本文件,给定任意两个单词,找出在这个文件中这两个单词的最短距离
- 编程珠玑: 14章 堆 14.2实现一个优先级队列,返回数组中最小值 -------解题总结
- 程序员面试金典——解题总结: 9.17中等难题 17.3设计一个算法,算出n阶乘有多少个尾随0
- 程序员面试金典——解题总结: 9.17中等难题 17.6给定一个整数数组,编写一个函数,找出索引m和n,只要将m和n之间的元素排好序,整个数组就是有序的。注意:n - m越小越好,也就是说,找出
- 编程珠玑: 15.1实现一个哈希表统计字符串出现次数 -------解题总结
- 程序员面试金典——解题总结: 9.17中等难题 17.8给定一个整数数组(有正数有负数),找出总和最大的连续数列,并返回总和
- 程序员面试金典——解题总结: 9.17中等难题 17.1编写一个函数,不用临时变量,直接交换两个数