【Trie树】模板题-POJ-2001

题意:

给你若干个单词,写出能每个单词的最短前缀

也就是说这个前缀能准确代表这个单词,和其他单词 without ambiguity 

思路:

建立字典树存下这几个单词,ct 数组记录每个节点的子节点数,显然子树宽度只有1的话,这个单词就被确定了,改造一下我们的 find_word 函数就行啦

哦。。这个结构体要怎么搞还坑了我一下,要向下面那样定义!

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

const int maxnode = 20050;
const int sigma_size = 30;

char str[1050][25];

///字母表为全体小写字母的 Trie
struct Trie
{
    int ch[maxnode][sigma_size];
    int val[maxnode];
    int ct[maxnode];
    int sz;         ///节点总数
    Trie() { sz = 1; memset(ch[0],0,sizeof(ch[0])); memset(ct,0,sizeof(ct)); }       ///初始时只有一个根节点
    int idx (char c) { return c - 'a'; }    ///字符c的编号

    ///插入字符串 s, 附加信息为 v。 注意 v 必须非0,因为 0 代表“本节点不是单词节点”
    void insert_word(char *s,int v){
        int u = 0, n = strlen(s);
        for(int i=0; i<n; i++){
            ct[u]++;
            int c = idx(s[i]);
            if(!ch[u][c]) {
                memset(ch[sz],0,sizeof(ch[sz]));
                val[sz] = 0;
                ch[u][c] = sz++;
            }
            u = ch[u][c];
        }
        val[u] = v;
        ct[u]++;
    }

    void find_word(char *s){
        int u = 0, n = strlen(s);
        for(int i=0; i<n; i++){
            int c = idx(s[i]);
            printf("%c",s[i]);
            u = ch[u][c];
            if(ct[u] == 1)break;
        }
        printf("\n");
    }
}my_trie;

int main()
{
    freopen("input.txt","r",stdin);
    int top = 0;
    while(scanf("%s",str[top]) != EOF){
        //cout<<str[top]<<endl;
        my_trie.insert_word(str[top],1);
        top++;
    }
    for(int i=0;i<top;i++)
    {
        printf("%s ",str[i]);
        my_trie.find_word(str[i]);
    }
    return 0;
}
    原文作者:Trie树
    原文地址: https://blog.csdn.net/cryssdut/article/details/38926305
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞