您的位置:首页 > 其它

HDU - 1251 统计难题(字典树)

2017-08-01 21:15 337 查看
点我看题

题意:就是题目的字面意思,求以某字符串为前缀的单词个数.

分析:字典树的基础题.本题字典树的结点加了exist元素会爆内存的,本来字典树就是牺牲空间换时间.

点我了解字典树(具体的还得自己动手才能掌握哇)

参考代码:

/*字典树 求前缀问题*/
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<iostream>

using namespace std;
//#define mem(a,b) memset(a,b,sizeof(a))
typedef struct TrieNode{
int count;//统计单词前缀出现的次数
struct TrieNode *child[26];//指向各子树的指针
//    bool exist;//标记该结点处是否构成单词(本题加了这个会爆内存啊啊啊)
}*Trie;

TrieNode* CreateTrieNode()
{
TrieNode* node = (TrieNode *)malloc(sizeof(TrieNode));
node->count = 0;
//    node->exist = false;
memset(node->child,0,sizeof(node->child));
return node;
}
Trie root = CreateTrieNode();//初始化字典树的根节点

void TrieInsert( char str[])
{
Trie node = root;
int p = 0;//str的下标
int id;
while( str[p] != '\n')
{
id = str[p]-'a';
if( node->child[id] == NULL)
node->child[id] = CreateTrieNode();
node = node->child[id];
p++;
node->count += 1;
}
//    node->exist = true;
}

int TrieSearch( char str[])
{
Trie node = root;
int p = 0;//str的下标
int id;
while( str[p] != '\n')
{
id = str[p]-'a';
node = node->child[id];
p++;
if( node == NULL)
return 0;
}
return node->count;
}

int main()
{
char str[12];
while( fgets(str,12,stdin) && strcmp(str,"\n"))//用的是ubuntu17.04 gets用不了,所以用了fgets
TrieInsert(str);

while( fgets(str,12,stdin))
printf("%d\n",TrieSearch(str));
return 0;
}


补充:一般用指针建树比较容易出错,嗯然后今天写了个数组实现字典树的,一个很**的问题出现了,之前说过我的电脑gets读取字符串编译过不了,今天混用fgets和scanf读取字符串,结果一直re==,都统一换成fgets就好了

/*字典树*/
/*数组实现*/
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>

using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
const int maxn = 1e6+10;
int TrieTree[maxn][26];//数组表示字典树
int cnt[maxn];//每个结点的前缀个数
int node;//所有结点个数

//根结点初始化
void init()
{
mem(TrieTree[0],0);
cnt[0] = 0;
node = 1;
}

void TireInsert( char word[])
{
int p = 0;//单词的下标
int root = 0;//word往下走的子树的根结点
while( word[p] != '\n')//fgets读取字符串时,后面的\n也被读入
{
int id = word[p]-'a';//用数字代替单词
if( TrieTree[root][id] == 0)//当前根结点的子树没有出现以id为根子树
{
//TrieTree
mem(TrieTree[node],0);
cnt[node] = 0;
TrieTree[root][id] = node++;//他是第多少个结点
}
cnt[TrieTree[root][id]]++;
root = TrieTree[root][id];
p++;
}
}

int TireSearch( char word[])
{
int p = 0;//word的下标
int root = 0;
int pos = 0;
while( word[p] != '\n')
{
int id = word[p]-'a';
if( TrieTree[root][id] == 0)
return 0;
else
pos = TrieTree[root][id];
root = TrieTree[root][id];
p++;
}
return cnt[pos];
}

int main()
{
char word[13];
init();
while( fgets(word,13,stdin) && strcmp(word,"\n"))
TireInsert(word);

while( fgets(word,13,stdin))
printf("%d\n",TireSearch(word));

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: