最短前缀(字典树)

来源:互联网 发布:中国公知奇葩言论 编辑:程序博客网 时间:2024/05/21 08:44

刚学了字典树,找了一道简单的模板题做了一下,下面每行前面部分的字符串是输入的,后面是其最小

前缀,下面是要求的输出格式:


carbohydrate carboh
cart cart
carburetor carbu
caramel cara
caribou cari
carbonic carboni
cartilage carti
carbon carbon
carriage carr
carton carto
car car
carbonate carbona


代码及注释如下:

#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>using namespace std;//树的结构struct Trie{    int cnt;  //每个字母是 cnt 个单词的前缀    Trie *next[26]; //一个指针数组,指向他下一个字母;        Trie()    {        cnt = 0;        for(int i = 0 ; i < 26 ; i ++)            next[i] = NULL;    }};Trie *root ;      //树根结点char a[1005][25]; //记录所有字符串,以便输出//每次传入一个字符串建树。void createTrie(char *str){    int len = strlen(str);    Trie *p = root;    Trie *q;                     for(int i=0; i<len; ++i)    {        int id = str[i]-'a';        if(p->next[id] == NULL)        {            q = new Trie;            q->cnt = 1;            p->next[id] = q;        }        else        {            p->next[id]->cnt++;        }        p = p->next[id];    }}//查找某个字符串对应的最小前缀,并返回每个字符串对应最小前缀的长度int findTrie(char *str){    int i;    int len = strlen(str);    Trie *p = root;    int cnt = 0;    for(i=0; i<len; ++i)    {        int id = str[i]-'a';        p = p->next[id];        if(p -> cnt > 1 )            cnt++;        else            break;    }    if(i == len)             return cnt;    else        return ++cnt;  //需要把第一次出现cnt为1时的节点也加入最小前缀}int main(){    int n=0;    root = new Trie;    while(scanf("%s", a[n])!=EOF)    {        getchar();        createTrie(a[n]);        n++;    }    for(int i=0; i<n; ++i)    {        cout << a[i] << " ";        int len = findTrie(a[i]);        for(int j=0; j<len; ++j)            printf("%c", a[i][j]);        cout << endl;    }    return 0;}



1 0
原创粉丝点击