poj 2001/1056 Trie树(求单词表的最短前缀/判断立即码)
2014-07-17 21:03
405 查看
题意:2001:输入若干单词组成单词表,求每个单词合理的最短前缀(通过前缀确定唯一的单词)。
1056:给定一系列01码,判断是否为立即码,即没有序列为另一个序列的前缀。
思路:使用trie树。其中的flag域用于标定通过这个节点是否有多个单词。初始为0(也就是插入第一个通过该节点的单词时),如果经过此节点有多于一个单词,则置为1。输出方法:从根开始,如果节点flag为1,则继续输出,为0则停止。版本2在trie结构体内进行初始化,运用了C++的写法。(最后是1056的代码)
2001 版本2:
1056:
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 ); 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++); } }
相关文章推荐
- poj 1056 判断前缀码
- POJ 2001 Shortest Prefixes 字典树经典题,求最短唯一前缀)
- 字典树---2001 POJ Shortest Prefixes(找最短前缀)
- POJ---2001 Shortest Prefixes[字典树---判断唯一前缀]
- poj 2001 Shortest Prefixes 【字典树】【找每一个字符串在字符串集里面的 最短且可唯一标识 的前缀】
- poj 1056 Trie树判断哈夫曼编码是否合法
- POJ 1056 immediately decodable (判断是否有前缀)
- poj 1056 判断前缀
- POJ 1056 IMMEDIATE DECODABILITY(字典树,判断有没有一个是另一个的前缀)
- 【原】 POJ 1056 IMMEDIATE DECODABILITY Trie树查找前缀 解题报告
- 字典树---2001 POJ Shortest Prefixes(找最短前缀)
- (Relax ST1.4)POJ 1056 IMMEDIATE DECODABILITY(判断一个字符串是否是另外一个字符串的前缀)
- poj 2001:Shortest Prefixes(字典树,经典题,求最短唯一前缀)
- POJ 2001 Trie树 (EOF 用ctrl+z表示 VS中) 一次AC!
- poj 2001 Shortest Prefixes Trie树
- Poj Trie树 水题整理 (Poj 1065+1204+2001+2418)
- POJ 3630 字典树 判断单词是否不覆盖
- HDU 1671 Phone List 判断前缀(Trie树)
- POJ 2513 (Trie树+欧拉通路+并查集判断连通)
- POJ 1584 A Round Peg in a Ground Hole(判断凸多边形,点到线段最短距离)