poj 2001/1056 Trie树(求单词表的最短前缀/判断立即码)

来源:互联网 发布:nginx 虚拟机配置 编辑:程序博客网 时间:2024/04/30 06:46

题意:2001:输入若干单词组成单词表,求每个单词合理的最短前缀(通过前缀确定唯一的单词)。

1056:给定一系列01码,判断是否为立即码,即没有序列为另一个序列的前缀。

思路:使用trie树。其中的flag域用于标定通过这个节点是否有多个单词。初始为0(也就是插入第一个通过该节点的单词时),如果经过此节点有多于一个单词,则置为1。输出方法:从根开始,如果节点flag为1,则继续输出,为0则停止。版本2在trie结构体内进行初始化,运用了C++的写法。(最后是1056的代码)

#include <stdio.h>#include <string.h>char s[1005][22];typedef struct trie{int flag;struct trie* next[26];}trie;trie t[20000];trie *alloc,*root;int n=-1;void init(){int i;alloc = t;root = alloc++;root->flag = 0;for(i = 0;i<26;i++)root->next[i] = NULL;}void insert(char s[22]){int i,j;trie *p,*q;p = root;for(i = 0;s[i]!='\0';i++){if(p->next[s[i]-'a']){//如果该节点已建立(和之前某单词前缀重复),flag置为1p = p->next[s[i]-'a'];p->flag = 1;}else{q = alloc++;q->flag = 0;for(j = 0;j<26;j++)//扫字符串用了i,此地不能再用q->next[j] = NULL;p->next[s[i]-'a'] = q;p = q;}}}void findprefix(char s[22]){int i;trie *p = root;for(i = 0;s[i]!='\0';i++){putchar(s[i]);p = p->next[s[i]-'a'];if(p->flag == 0)break;}putchar('\n');}int main(){int i,j;freopen("a.txt","r",stdin);init();while(scanf("%s",s[++n])!=EOF)insert(s[n]);for(i = 0;i<=n;i++){printf("%s ",s[i]);findprefix(s[i]);}return 0;}


2001 版本2:

#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#define N 1040#define INF 0x3fffffffusing namespace std;char s[1005][22];int num = 0;struct node{    int flag;    struct node* next[26];    node(){        flag = 0;        memset(next,NULL,sizeof(next));    }}t[20005],*root;void insert(char x[22]){    int i;    struct node *p = root;    for(i = 0;x[i]!='\0';i++){        if(!p->next[x[i]-'a']){            num++;            p->next[x[i]-'a'] = t+num;        }else            p->next[x[i]-'a']->flag = 1;        p = p->next[x[i]-'a'];    }}void output(char x[22]){    int i;    struct node *p = root;    for(i = 0;x[i]!='\0';i++){        putchar(x[i]);        p = p->next[x[i]-'a'];        if(!p || p->flag == 0)            break;    }    putchar('\n');}int main(){    int i,len = 0;    root = t;    while(scanf("%s",s[++len])!=EOF){        insert(s[len]);    }    for(i = 1;i<=len;i++){        printf("%s ",s[i]);        output(s[i]);    }    return 0;}


1056:

#include <stdio.h>#include <string.h>typedef struct node{int flag;struct node *next[2];}Node;Node tree[100000],*root,*alloc;char s[1025];int c = 1,flag;void init(){flag = 1;alloc = tree;root = alloc++;root->flag = 0;root->next[0] = root->next[1] = NULL;}int insert(char *s){int i,flag = 1;Node *p,*q;p = root;for(i = 0;s[i]!='\0';i++){if(!p->next[s[i]-'0']){flag = 0;q = alloc++;q->flag = 0;q->next[0] = q->next[1] = NULL;p->next[s[i]-'0'] = q;}p = p->next[s[i]-'0'];if(p->flag)return 0;}p->flag = 1;return flag==0;}int main(){//freopen("a.txt","r",stdin);while(scanf("%s",s)!=EOF){int j;init();do{if(flag){j = insert(s);if(!j)flag = 0;}scanf("%s",s);}while(strcmp(s,"9"));if(flag)printf("Set %d is immediately decodable\n",c++);elseprintf("Set %d is not immediately decodable\n",c++);}}


0 0