hdu 1247~~字典树

来源:互联网 发布:升级数据 日月 编辑:程序博客网 时间:2024/05/16 09:22

题目连接:

http://acm.hdu.edu.cn/showproblem.php?pid=1247

题目意思:

给定一些单词(按字典序给出), 按字典序输出所有满足条件的单词(条件:该单词由其它两个单词构成)

算法描述:

转载http://blog.csdn.net/azheng51714/article/details/7836687

先把所有的单词构造成一颗trie图,然后对所有的单词进行枚举,在trie图上面判断一个单词是否由其它两个单词构成,具有的做法是先沿着路径一直走,如果走到某个节点,该节点为一个单词的结尾,那么再对剩余的单词再从trie图的根开始遍历,看是否能和一个单词匹配,若匹配成功则该单词满足要求,否则继续进行匹配...

题目代码:

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#define MAX 50005#define len 26using namespace std;char str[MAX][27+27];//不知道为什么27,题目意思没说长度struct node{    bool Y;    node *next[len];//注意,这里是指针呀,指向下一个节点,不是节点值    node(){        Y = false;        memset(next,0,sizeof(next));//指针赋值null,用0代替吗?可以    }};void insert(node *rt,char *s){    node *p = rt;    int i=0,k;    while(s[i]){        k=(int)(s[i]-'a');        if(p->next[k]==NULL)//0还是NULL?????是NULL            p->next[k]=new node();        p=p->next[k];        i++;    }    p->Y=true;}bool search(node *rt,char s[]){    int i=0,k;    int stack[27+27],top=0;    node *p = rt;    while(s[i]){        k=(int)(s[i]-'a');        if(p->next[k]==NULL)return false;//如果只有一个节点,那么不能找到组成他的2个子串        p=p->next[k];        if(p->Y==true&&s[i+1])stack[top++]=i+1;//将节点位置入栈,因为一个串可能有很多节点,不一定用栈        i++;//上面的判断s[i+1]的目的是将最后一个属于自己的节点不入栈,为什么???        //暂时找不到反例,如果将i+1入栈了,后面会导致数组超过了实际长度,尽管可能不会影响结构,但是如果数组        //刚好一样大小的话,就会越界    }    while(top)    {        i=stack[--top];//从后一个开始        p=rt;        bool ok=true;        while(s[i]){//可能有问题            k=(int)(s[i++]-'a');//为什么i放在最后自增就不行            if(p->next[k]==NULL){                ok = false;                break;//必须要加            }            p=p->next[k];        }        if(ok&&p->Y)return true;    }    return false;}int main(){    freopen("1247.txt","r",stdin);    int i=0;    node *root=new node();    while(gets(str[i]))    {        insert(root,str[i]);        i++;    }    for(int j=0;j<i;j++)    {        if(search(root,str[j]))            printf("%s\n",str[j]);    }    return 0;}

0 0
原创粉丝点击