题意: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置为1 p = 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 0x3fffffff using 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++); else printf("Set %d is not immediately decodable\n",c++); } }