HDOJ 1251 统计难题——第二次用字典树AC题目,写一下解题报告

    第一次用字典树+BFS的方法统计以给定字符串为前缀的单词数目,超时了。百思不得其解,然后我看了一下讨论版里的一位同学的AC代码。豁然开朗,立刻明白了求解相同前缀的单词个数的最简单的解法。

    其实在建一科字典树的时候,每插入一个字母,就相当于给以当前已经插入的串为前缀的单词增加了一个。这样,统计的时候就不用BFS了。哈哈。废话不多说了,贴出我的代码,跟大家分享,造福后代。

#include<iostream>
#include<string.h>
#include<queue>
using namespace std;

const int Branch = 26;

struct Trie
{
	int count;
	Trie * next[Branch];
};	//字典树结点


//
void insert(Trie * root, char * str)
{
	Trie * p = root;
	while(*str)
	{
		int seqNum = *str - 'a';
		if(!p->next[seqNum])
		{
			p->next[seqNum] = new Trie();
			memset(p->next[seqNum], 0, sizeof(Trie));
		}
		p = p->next[seqNum];
		p->count ++;

		str++;	//忘记写这句话,导致内存耗尽,最终死机
	}
	//p->tail = true;
}

//
int statistics(Trie * root, char * str)
{
	Trie * p = root;

	while(*str)
	{
		int seqNum = *str - 'a';
		if(p->next[seqNum] == NULL) return 0;
		else 
		{
			p = p->next[seqNum];
			str ++;
		}
	}

	int sum = p->count;
	/*
	int sum = 0;
	queue<Trie *> q;
	q.push(p);
	while(!q.empty())
	{
		Trie * cur = q.front();	q.pop();
		if(cur->tail) sum ++;
		for(int i=0; i<Branch; i++)
			if(cur->next[i]) q.push(cur->next[i]);
	}*/
	return sum;
}


int main()
{
	char word[11];
	Trie * root = new Trie();
	memset(root, 0, sizeof(Trie));

	while(gets(word))
	{
		if(word[0] == '\0') break;

		insert(root, word);
	}

	while(scanf("%s", word) != EOF)
	{
		int sum = statistics(root, word);
		cout << sum << endl;
	}
	system("pause");
	return 0;
}

       代码里那段被注释掉的代码块是之前BFS求解相同前缀数目的解法。也是一种求解方法,保留了。哈哈。第二次AC字典树的问题。


你可能感兴趣的:(struct,null,System,insert,branch,statistics)