hdu 1247 Hat’s Words 字典树 二次查找

Hat’s Words


Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 8693    Accepted Submission(s): 3127




Problem Description
A hat’s word is a word in the dictionary that is the concatenation of exactly two other words in the dictionary.
You are to find all the hat’s words in a dictionary.
 


Input
Standard input consists of a number of lowercase words, one per line, in alphabetical order. There will be no more than 50,000 words.
Only one case.
 


Output
Your output should contain all the hat’s words, one per line, in alphabetical order.
 


Sample Input
a
ahat
hat
hatword
hziee
word
 


Sample Output
ahat

hatword


题意:输出由两个单词构成的单词. 


先建树,然后查找.  找到前缀后,再找后缀. 都找到了 就输出.

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAX 26

struct Trie   
{   
    Trie *next[MAX];   
    int v;   //根据需要变化
};   
 
Trie root;

void createTrie(char *str)
{
    int len = strlen(str);
    Trie *p = &root, *q;
    for(int i=0; i<len; ++i)
    {
        int id = str[i]-'a';
        if(p->next[id] == NULL)
        {
            q = (Trie *)malloc(sizeof(Trie));
            q->v = 1;    //初始v==1
            for(int j=0; j<MAX; ++j)
                q->next[j] = NULL;
            p->next[id] = q;
            p = p->next[id];
        }
        else
        {
            p = p->next[id];//已经建过边的点 不改变值,不然 会把-1 这个值改变,就找不到单词了
        }
    }
    p->v = -1;   //若为结尾,则将v改成-1表示  字典树中出现-1 就表示到此点为一个单词
}

int findTrie(char *str,int n)//n表示第几次查找
{
    int len = strlen(str);
    Trie *p = &root;
    for(int i=0; i<len; ++i)
    {
        int id = str[i]-'a';
        p = p->next[id];
        if(p == NULL)   //若为空集,表示不存以此为前缀的串
            return 0;
        if(p->v == -1&&i==len-1&&n==2)   //第二次查找的时候 找到了str这个单词  
            return 1; 
		if(p->v == -1&&n==1&&i!=len-1)//第一次查找,找到str的前缀
		{
			if(findTrie(str+i+1,2)==1)//尝试进行第二次查找 ,返回1 表示str 除前缀外剩下的部分也找到了. 就是题意要求的两个词组成
			{
				printf("%s\n",str);
				return -1;
			}
		}
	}
    return 0;   //此串是字符集中某串的前缀 无意义
}
int dealTrie(Trie* T)
{
    int i;
    if(T==NULL)
        return 0;
    for(i=0;i<MAX;i++)
    {
        if(T->next[i]!=NULL)
            dealTrie(T->next[i]);
    }
    free(T);
    return 0;
}


char str[50010][20];
int main()
{
	root.v=1;
	int k=0;
	while(scanf("%s",str[k])!=EOF)
	{
		createTrie(str[k]); 
		k++;
	}
	for(int i=0;i<k;i++)
	{
		findTrie(str[i],1);
	}
	return 0;
}

/*
a
ab
abcd
cd
*/
 


 

你可能感兴趣的:(字典树)