您的位置:首页 > 职场人生

程序员面试金典——解题总结: 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐