题目链接
poj 1056 :http://poj.org/problem?id=1056
hdu 1305 :http://acm.hdu.edu.cn/showproblem.php?pid=1305
zoj 1808 :http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=808
Description
Input
Output
Sample Input
01 10 0010 0000 9 01 10 010 0000 9
Sample Output
Set 1 is immediately decodable Set 2 is not immediately decodable
Source
题意:找一堆单词中是否存在一个单词是另一个单词的前缀。
代码如下:
#include <cstdio>
#include <cstring>
#include <malloc.h>
#include <iostream>
using namespace std;
#define MAXN 2
typedef struct Trie
{
int v;//根据需要变化
Trie *next[MAXN];
//next是表示每层有多少种类的数,如果只是小写字母,则26即可,
//若改为大小写字母,则是52,若再加上数字,则是62了
} Trie;
Trie* root;
void createTrie(char *str)
{
int len = strlen(str);
Trie *p = root, *q;
for(int i = 0; i < len; i++)
{
int id = str[i]-'0';
if(p->next[id] == NULL)
{
q = (Trie *)malloc(sizeof(Trie));
q->v = 1;//初始v==1
for(int j = 0; j < MAXN; j++)
q->next[j] = NULL;
p->next[id] = q;
p = p->next[id];
}
else
{
// p->next[id]->v++;
p = p->next[id];
}
}
p->v = -1;//若为结尾,则将v改成-1表示
}
int findTrie(char *str)
{
int len = strlen(str);
Trie *p = root;
for(int i = 0; i < len; i++)
{
int id = str[i]-'0';
p = p->next[id];
if(i < len-1)//注意
{
if(p->v==-1)
{
return -1;
}
}
/* if(p == NULL) //若为空集,表示不存以此为前缀的串
return 0;
if(p->v == -1) //字符集中已有串是此串的前缀
return -1;*/
}
return 1;//自身
}
int main()
{
char str[15][20];
int c = 1;
while(scanf("%s",str[0])!=EOF)
{
root = (Trie *)malloc(sizeof(Trie));
for(int i = 0; i < MAXN; i++)
root->next[i] = NULL;
createTrie(str[0]);
int k = 1;
while(scanf("%s", str[k])&&str[k][0]!='9')
{
createTrie(str[k++]);
}
int i;
for(i = 0; i < k; i++)
{
int flag = findTrie(str[i]);
if(flag == -1)//有相同前缀
{
printf("Set %d is not immediately decodable\n",c++);
break;
}
}
if(i>=k)//没有相同前缀
{
printf("Set %d is immediately decodable\n",c++);
}
}
return 0;
}
poj1056 & hdu1305 & zoj1808 Immediate Decodability(字典树变形)
原文地址:http://blog.csdn.net/u012860063/article/details/39077139