POJ 2001 Shortest Prefixes(字典树)

来源:互联网 发布:mac itunes铃声在哪里 编辑:程序博客网 时间:2024/04/26 18:22

解析:

找出能唯一标示一个字符串的最短前缀。

解析:

Trie树。val表示有多少个单词节点。先将所有单词保存在Trie树中,然后一个一个地查找,当到达某个节点时val==1。表示到当前位置只有一条路,那么从根到该节点组成的字符串便是该单词的最短前缀。

总结:

RE了一个下午,才知道,遍历字符串的时候要先求出字符串的长度,然后根据这个长度进行遍历,而我之前是用指针偏移来做的,这样可能会RE。

my code

#include <cstdio>#include <cstring>#include <algorithm>using namespace  std;const int MAXN = 1000 + 10;const int maxnode = 100005;const int sigma_size = 26;char str[MAXN][25];int tot;int ch[maxnode][sigma_size];char val[maxnode];struct Trie {    int sz;    Trie() {sz = 1; memset(ch[0], 0, sizeof(ch[0]));}    int idx(char c) { return c - 'a'; }    void insert(char *s) {        int u = 0, n = strlen(s);        for(int i = 0; i < n; i++) {            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]++;        }    }    void query(char *s) {        int u = 0, n = strlen(s);        for(int i = 0; i < n; i++) {            putchar(s[i]);            int c = idx(s[i]);            if(val[ch[u][c]] == 1) return ;            u = ch[u][c];        }    }};int main() {    tot = 0;    Trie trie;    while(scanf("%s", str[tot]) != EOF) {        trie.insert(str[tot]);        tot++;    }    for(int i = 0; i < tot; i++) {        printf("%s ", str[i]);        trie.query(str[i]);        printf("\n");    }    return 0;}
0 0
原创粉丝点击