Hihocode Trie树代码

今天AC了HiHocode 的第二道题,因为hihocode并不给测试提示,所以难度感觉leetcode高一些,比较恶心。

但是当出现AC的时候真是太高兴了,废话不多说,进入正题

我是华丽丽的分割线!

==============================================================

hihocode很善意的提供了提示,虽然分了三个,但是关键点还是两个

一是如何构建树

二是如何查询前置单词

Trie树是以边来保存字符的,博主一开始误以为是节点保存了,耗费了一点脑力。

另外,hihocode也提示了需要边插入边统计,于是我们的构造体就这样出现了。

需要注意的是hihocode 定义重复的单词算两个,博主一开始去掉了重复单词,于是WA了很久。

struct Node
{
	bool isWord;
	Node *child[Max];//save edge
	int L[Max];//save count

	Node()
	{
		isWord = false;

		for (int i = 0; i < Max; i++)
		{
			child[i] = NULL;			
		}

		for (int i = 0; i < Max; i++)
		{
			L[i] = 0;
		}
	}

	~Node()
	{
		for (int i = 0; i < Max; i++)
		{
			delete child[i];
		}
	}
};

插入单词:

void Insert(string word)
{
	Node *tempRoot = root;
	for (int i = 0; i < word.length(); i++)
	{
		tempRoot->L[word[i]-'a']++;
		if (tempRoot->child[word[i]-'a'] != NULL)
		{			
			tempRoot = tempRoot->child[word[i]-'a'];
		}
		else
		{
			Node *newNode = new Node();
			tempRoot->child[word[i]-'a'] = newNode;
			tempRoot = tempRoot->child[word[i]-'a'];
		}
		if (i == word.length() - 1)
		{
			if (tempRoot->isWord == false)
			{
				tempRoot->isWord = true;
			}			
		}
	}
}

因为是一边查找一边统计,所以其实可以不完全符合trie树也可以,是单词的那个节点不做标记也无法影响结果

查找单词/前缀 数量:

int find(string word)
{
	Node *tempRoot = root;
	for (int i = 0; i < word.length(); i++)
	{
		if (tempRoot->child[word[i]-'a'] == NULL)return 0;
		else
		{			
			if (i == word.length() - 1) return tempRoot->L[word[i]-'a'];
			tempRoot = tempRoot->child[word[i]-'a'];
		}
	}
}

接下来就贴上所有的代码

所有的代码中包含减去重复单词的函数,但是并没有用到:

#include<iostream>
#include<string>
using namespace std;

const int Max = 26;
struct Node
{
	bool isWord;
	Node *child[Max];//save edge
	int L[Max];//save count

	Node()
	{
		isWord = false;

		for (int i = 0; i < Max; i++)
		{
			child[i] = NULL;			
		}

		for (int i = 0; i < Max; i++)
		{
			L[i] = 0;
		}
	}

	~Node()
	{
		for (int i = 0; i < Max; i++)
		{
			delete child[i];
		}
	}
};

Node * root = new Node();

void minusDuplicate(string word)
{
	Node *tempRoot = root;
	for (int i = 0; i < word.length(); i++)
	{
		tempRoot->L[word[i]-'a']--;
		tempRoot = tempRoot->child[word[i]-'a'];
	}
}

void Insert(string word)
{
	Node *tempRoot = root;
	for (int i = 0; i < word.length(); i++)
	{
		tempRoot->L[word[i]-'a']++;
		if (tempRoot->child[word[i]-'a'] != NULL)
		{			
			tempRoot = tempRoot->child[word[i]-'a'];
		}
		else
		{
			Node *newNode = new Node();
			tempRoot->child[word[i]-'a'] = newNode;
			tempRoot = tempRoot->child[word[i]-'a'];
		}
		if (i == word.length() - 1)
		{
			if (tempRoot->isWord == false)
			{
				tempRoot->isWord = true;
			}			
		}
	}
}

int find(string word)
{
	Node *tempRoot = root;
	for (int i = 0; i < word.length(); i++)
	{
		if (tempRoot->child[word[i]-'a'] == NULL)return 0;
		else
		{			
			if (i == word.length() - 1) return tempRoot->L[word[i]-'a'];
			tempRoot = tempRoot->child[word[i]-'a'];
		}
	}
}



int main()
{
	int count = 0;
	cin >> count;
	string insertStr;
	for (int i = count; i > 0; i--)
	{
		cin >> insertStr;
		Insert(insertStr);
	}
	cin >> count;
	for (int i = count; i > 0; i--)
	{
		cin >> insertStr;
		cout<<find(insertStr)<<endl;
	}
	return 0;
}

    原文作者:Trie树
    原文地址: https://blog.csdn.net/u012204919/article/details/40656491
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞