POJ2001 Shortest Prefixes

题目链接:http://poj.org/problem?id=2001

另一种字典树的写法……

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
struct trie{
    int ch[100100][30];
    int num[100100];
    int sz;
    void reset(){
        memset(ch[0], 0, sizeof(ch[0]));
        memset(num, 0, sizeof(num));
        sz = 1;
    }
    int idx(char c){
        return c - 'a';
    }
    void insert(string s){
        int u = 0, n = s.size();
        for (int i = 0; i < n; i++){
            int c = idx(s[i]);
            if (!ch[u][c]){
                ch[u][c] = sz;
                memset(ch[sz], 0, sizeof(sz));
                num[sz] = 1; sz += 1;
            }
            else num[ch[u][c]] += 1;
            u = ch[u][c];
        }
    }
    void print(string s){
        int u = 0, n = s.size();
        for (int i = 0; i < n; i++){
            int c = idx(s[i]);
            putchar(s[i]);
            if (num[ch[u][c]] == 1) return;
            u = ch[u][c];
        }
    }
}t;
string s[2010];
int main(){
    //freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
    int n = 0;
    t.reset();
    while (cin >> s[n]) t.insert(s[n++]);
    for (int i = 0; i < n; i++){
        cout << s[i] << " ";
        t.print(s[i]);
        printf("\n");
    }
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
struct trie{
    int num;
    int next[30];
    int init(){
        num = 1;
        memset(next, -1, sizeof(next));
        return 0;
    }
}tree[100100];
int sz = 1;
const int rt = 0;
int idx(char c){
    return c - 'a';
}
void insert(string s){
    int p = rt, n = s.size();
    for (int i = 0; i < n; i++){
        int v = idx(s[i]);
        if (tree[p].next[v] == -1){
            tree[p].next[v] = sz;
            tree[sz].init();
            sz += 1;
        }
        else tree[tree[p].next[v]].num += 1;
        p = tree[p].next[v];
    }
}
void print(string s){
    int p = rt, n = s.size();
    for (int i = 0; i < n; i++){
        int v = idx(s[i]);
        putchar(s[i]);
        if (tree[tree[p].next[v]].num == 1) return;
        p = tree[p].next[v];
    }
}
void init(){
    sz = 1;
    tree[0].init();
}
string s[2010];
int main(){
    init();
    int n = 0;
    while(cin >> s[n]) insert(s[n++]);
    for (int i = 0; i < n; i++){
        cout << s[i] << " ";
        print(s[i]);
        printf("\n");
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值