POJ 2001 Shortest Prefixes (字典树,简单)

给你一堆字符串,让你输出每个字符串着这些字符串中可以单独识别的前缀。因为是直接找的字典树的题目来做,所i就是用字典树了。

字典树的每一个结点记录某一个字符出现的次数,之后,遍历每一个字符串,当出现第一个次数为1的点,则记录下来,输出从字符串头到这个点的字符,则为这个字符串的独立前缀。

交了N多次,一直在WA,很纠结,最后更新了首节点的数量,才AC 的,好痛苦的经历。


#include <cstdio>
#include <cstdlib>
#include <cstring>


const int branchNum = 26;
const int trieNodeNum = 21000;


struct Trie_node{
    int isStr;
    int next[branchNum];
}trie[trieNodeNum];
int trieTop = 0;


void init(){
    int i;


    trieTop = 0;
    for (i = 0; i < trieNodeNum; i++){
        trie[i].isStr = 0;
        for (int j = 0; j < 26; j++){
            trie[i].next[j] = -1;
        }
    }
}


void insert(const char *word){


    int location = 0;


    trie[location].isStr ++; //要先添加一个,即是trie第一个结点的个数要加一,不然会WA
    while (*word){
        if (trie[location].next[*word - 'a'] == -1){
            trie[location].next[*word - 'a'] = ++trieTop;
        }
        location = trie[location].next[*word - 'a'];
        trie[location].isStr ++;
       // printf("location: %d\n", trieTop);
        word++;
    }
    //trie[location].isStr = true;
}


bool search(const char *word){
    int location = 0;


    while (*word && location != -1){
        location = trie[location].next[*word - 'a'];
        word ++;
    }
    return location != -1 && trie[location].isStr == 0;
}


void print(const char *word){
   int location = 0;
   const char *a = word;


    while (*word && location != -1){
        location = trie[location].next[*word - 'a'];
        printf("%d %c %d\n", word - a, *word, trie[location].isStr);
        word++;
    }
}


char str[1100][30];
int prefix[1100];


int search_prefix(const char *word){
    int last = 0;
    int location = 0;
    int len = 0;
    const char *a = word;


    while (*word && trie[location].isStr){
        if (trie[location].isStr == 1){
            last = len;
            break;
        }
        location = trie[location].next[*word - 'a'];
        word++;
        len ++;
    }
    if(last == 0){
        last = strlen(a);
    }
  // printf("\nlast : %d\n", strlen(word));
    return last;
}


int main(void){
    int len = 0;
    int i;


    init();
    while (scanf("%s", str[len]) != EOF){
        insert(str[len]);
        len++;
    }
    for (i = 0; i < len; i++){
        prefix[i] = search_prefix(str[i]);
        printf("%s ", str[i]);
        for (int j = 0; j < prefix[i]; j++){
            printf("%c", str[i][j]);
        }
        printf("\n");
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值