leecode 解题总结:208. Implement Trie (Prefix Tree)

#include <iostream>
#include <stdio.h>
#include <vector>
#include <string>
using namespace std;
/*
问题:
Implement a trie with insert, search, and startsWith methods.

Note:
You may assume that all inputs are consist of lowercase letters a-z.

分析:实现一个前缀树,能够支持插入,查找,以某字符串开始 方法
明显是a~z,每次插入一个字符串,遍历字符串的每一个字符,如果
当前节点的孩子节点中对应该字符的节点没有建立,就建立,同时处理下一个字符。
插入的过程是一个递归的过程,查找的过程也是一个递归的过程。
同时需要设定一个当前节点是否为叶节点的标记,当遍历到最后一个非空字符,
令该标记为真

输入:
5(指令个数)
insert zhuwenping
search zhuwenpin
search zhuwenping(所有查找的单词)
startswith zhu
startswith zhuma(所有startswith的单词)

7
insert abc
search abc
search ab
insert ab
search ab
insert ab
search ab
输出:
flase,true,true,false
true,false,true,true

报错:题目可能存在对多个自复查un进行插入
Runtime Error Message:
Line 36: member call on null pointer of type 'struct TrieNode'
Last executed input:
["Trie","insert","search","search","insert","search","insert","search"]
[[],["abc"],["abc"],["ab"],["ab"],["ab"],["ab"],["ab"]]

关键:
1 	TrieNode()
	{
		_isFinish = false;
		//初始化设置数组为空,否则后续无法处理
		memset(_childs , NULL , sizeof(_childs) );
	}
*/

const int CHILD_SIZE = 26;
class TrieNode
{
public:
	TrieNode()
	{
		_isFinish = false;
		//初始化设置数组为空,否则后续无法处理
		memset(_childs , NULL , sizeof(_childs) );
	}
	void insert(string& word, int pos)
	{
		if(word.empty() || pos < 0 || pos >= word.length())
		{
			return;
		}
		char ch = word.at(pos);
		int index = ch - 'a';
		if(index < 0 || index >= 26)
		{
			return;
		}
		//如果当前节点的子节点没有建立,就新建一个
		TrieNode* childNode = _childs[index];
		if(NULL == childNode)
		{
			childNode = new TrieNode();
			_childs[index] = childNode;
		}
		//如果当前字符是字符串最后一个字符,就设置节点的结束标记为真
		if(pos == word.length() - 1)
		{
			childNode->_isFinish = true;
		}
		//递归对孩子节点进行处理
		childNode->insert(word , pos + 1);
	}

	//查询某字符串,这个是完整查找,必须找到最后一个字符都符合
	bool search(string& word , int pos)
	{
		if(word.empty() || pos < 0 || pos >= word.length())
		{
			return false;
		}
		char ch = word.at(pos);
		int index = ch - 'a';
		if(index < 0 || index >= 26)
		{
			return false;
		}
		//如果当前节点的子节点没有建立,就新建一个
		if(NULL == _childs[index])
		{
			return false;
		}
		TrieNode* childNode = _childs[index];
		//如果当前查找的是最后一个字符,并且对应该字符的结束标记为真,就是结束
		if(pos == word.length() - 1 && childNode->_isFinish)
		{
			return true;
		}
		return childNode->search(word , pos + 1);
	}

	bool startsWith(string& word , int pos)
	{
		if(word.empty() || pos < 0 || pos >= word.length())
		{
			return false;
		}
		char ch = word.at(pos);
		int index = ch - 'a';
		if(index < 0 || index >= 26)
		{
			return false;
		}
		//如果当前节点的子节点没有建立,就新建一个
		if(NULL == _childs[index])
		{
			return false;
		}
		TrieNode* childNode = _childs[index];
		//如果当前查找的是最后一个字符,
		if(pos == word.length() - 1 )
		{
			return true;
		}
		return childNode->startsWith(word , pos + 1);
	}
public:
	bool _isFinish;
	TrieNode* _childs[CHILD_SIZE];
};

class Trie {
public:
    Trie() {
        //初始化一个根节点
		_root = new TrieNode();
    }

	~Trie()
	{
		deleteNode(_root);
	}
    
    void insert(string word) {
		if(word.empty())
		{
			return;
		}
		_root->insert(word , 0 );
    }
    
    /** Returns if the word is in the trie. */
    bool search(string word) {
		if(word.empty())
		{
			return false;
		}
		bool isFind = _root->search(word , 0 );
		return isFind;
    }
    
    /** Returns if there is any word in the trie that starts with the given prefix. */
    bool startsWith(string prefix) {
		if(prefix.empty())
		{
			return false;
		}
        bool isFind = _root->startsWith(prefix , 0 );
		return isFind;
    }

	void deleteNode(TrieNode* root)
	{
		if(!root)
		{
			return;
		}
		if(NULL == root->_childs)
		{
			return;
		}
		//先递归
		for(int i = 0 ; i < CHILD_SIZE ; i++)
		{
			if(NULL != root->_childs[i])
			{
				deleteNode(root->_childs[i]);
			}
		}
		if(root)
		{
			delete root;
			root = NULL;
		}
	}

private:
	TrieNode* _root;//根节点
};

void process()
{
	 vector<int> nums;
	 string value;
	 int commandNum;
	 vector<int> result;
	 string command;
	 while(cin >> commandNum)
	 {
		Trie obj;
		for(int i = 0 ; i < commandNum ; i++)
		{
			cin >> command >> value;
			if("insert" == command)
			{
				obj.insert(value);
			}
			else if("search" == command)
			{
				bool result = obj.search(value);
				if(result)
				{
					cout << "true" << endl;
				}
				else
				{
					cout << "false" << endl;
				}
			}
			else if("startswith" == command)
			{
				bool result = obj.startsWith(value);
				if(result)
				{
					cout << "true" << endl;
				}
				else
				{
					cout << "false" << endl;
				}
			}
		}
		cout << endl;
	 }
}

int main(int argc , char* argv[])
{
	process();
	getchar();
	return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值