梦,才是最真的现实

导航

hdu 1247 字典树

题意:给你一部分单词,让你找出所有这样的单词:a+b=c,就是一个单词,由另外两个单词串联而成

解题思路:先输入全部单词,构建一棵tire树,然后枚举所有单词,对单词进行查找,查找过程中经过的单词节点记录下来,(已经确定有一个单词了,寻找另一个单词是否存在)然后从这个节点再重新搜(树根开始),如果另一个单词也存在,则符合要求

最后按照字典序排下序输出即可

sample:

a
ahat
hat
hatword
hziee
word

构建了这样一棵tire树,我们搜索下hatword,搜索过程中发现hat是一个单词,然后我们从根开始搜索word是否存在,如果存在,就符合,具体实现请看代码

#include<stdio.h>
#include<string.h>
#include<vector>
#include<stdlib.h>
#define val 50005
using namespace std;
int cmp(const void *a,const void*b)
{
	return strcmp((char*)a,(char *)b);
}
struct Dictree
{
	bool end;
	Dictree *next[26];
}*root;
vector<int> pos;//记录可能的节点
void create_tree();
void insert(char *);//构建tire树
void search(char *);//查找节点
bool find(char *);//查找另一个单词
char s[val][20];
char ans[val][20];
int main()
{
	int index=0,v=0;
	int i,j,k;
	create_tree();
	while(scanf("%s",s[index++])!=EOF)
		insert(s[index-1]);
	for(i=0;i<index;i++)
	{
		pos.clear();
		search(s[i]);
		for(j=0;j<pos.size();j++)
		{
			if(find(s[i]+pos[j])==true)
			{
				strcpy(ans[v++],s[i]);
					break;
			}
		}
	}
	qsort(ans,v,sizeof(ans[0]),cmp);
	for(i=0;i<v;i++)
		puts(ans[i]);
	return 0;
}
void insert(char *s)
{
	int i,j;
	Dictree *p,*t;
	p=root;
	for(i=0;s[i];i++)
	{
		if(p->next[s[i]-'a']==NULL)
		{
			t=(Dictree*)malloc(sizeof(Dictree));
			t->end=false;
			memset(t->next,NULL,sizeof(t->next));
			p->next[s[i]-'a']=t;
		}
		p=p->next[s[i]-'a'];
	}
	p->end=true;
}
void create_tree()
{
	root=(Dictree*)malloc(sizeof(Dictree));
	root->end=false;
	memset(root->next,NULL,sizeof(root->next));
}
void search(char*s)
{
	int i;
	Dictree *p=root;
	for(i=0;s[i+1];i++)
	{
		p=p->next[s[i]-'a'];
		if(p->end) pos.push_back(i+1);
	}
}
bool find(char *s)
{
	int i;
	Dictree *p=root;
	for(i=0;s[i];i++)
	{
		if(p->next[s[i]-'a']==NULL)
			return false;
		else p=p->next[s[i]-'a'];
	}
	if(p->end) return true;
	else return false;
}


posted on 2012-08-20 15:34  梦,才是最真的现实  阅读(118)  评论(0编辑  收藏  举报