今天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;
}