一.输入查找输入
Phone List
Given a list of phone numbers, determine if it is consistent in the sense that no number is the prefix of another. Let's say the phone catalogue listed these numbers:
- Emergency 911 - Alice 97 625 999 - Bob 91 12 54 26
In this case, it's not possible to call Bob, because the central would direct your call to the emergency line as soon as you had dialled the first three digits of Bob's phone number. So this list would not be consistent.
The first line of input gives a single integer, 1 <= t <= 40, the number of test cases. Each test case starts with n, the number of phone numbers, on a separate line, 1 <= n <= 10000.Then follows n lines with one unique phone number on each line. A phone number is a sequence of at most ten digits.
For each test case, output "YES" if the list is consistent, or "NO" otherwise.
2 3 911 97625999 91125426 5 113 12340 123440 12345 98346
NO YES
zoj 2876
题目大意就是判断是否某个字符串是否是另一个字符串的前缀,用到了Trie数。整理一下模板。(参考大神的)
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define MAX 10
using namespace std;
typedef struct Trie
{
bool flag;
Trie *next[MAX];
} Trie;
Trie *root;
void insert(char *word)//创建字典树
{
int i;
Trie *tem = root;
while(*word!='\0')
{
if(tem->next[*word-'0']==NULL)
{
Trie *cur = (Trie *)malloc(sizeof(Trie));
for(i=0; i<MAX; i++)
cur->next[i]=NULL;
cur->flag=false;
tem->next[*word-'0']=cur;
}
tem = tem->next[*word-'0'];
word++;
}
tem->flag=true;
}
int search(char *word)//递归查找
{
int i;
Trie *tem = root;
for(i=0; word[i]!='\0'; i++)
tem=tem->next[word[i]-'0'];
return (tem!=NULL&&tem->flag==true);//tem!=null是为了防止自己找到自己,而做出的限制。(查找太妙了)
}
void del(Trie *cur)//释放空间(必须有)
{
int i;
for(i=0; i<MAX; i++)
{
if(cur->next[i]!=NULL)
del(cur->next[i]);
}
free(cur);
}
int main()
{
int t,n,i,len;
bool flag;
char phone_num[10005][20];
char num[20];
scanf("%d",&t);
while(t--)
{
root = (Trie *)malloc(sizeof(Trie));
root->flag=false;
for(i=0; i<MAX; i++)
root->next[i]=NULL;
flag = true;
scanf("%d",&n);
for(i=0; i<n; i++)
{
scanf("%s",phone_num[i]);
insert(phone_num[i]);
}
for(i=0; i<n; i++)
{
len = strlen(phone_num[i]);
memset(num,'\0',sizeof(num));
for(int j=0; j<len-1; j++)
{
num[j]=phone_num[i][j];//将字符串付给数组,用数组比较
if(search(num))
{
flag = false;
break;
}
}
}
if(flag)printf("YES\n");
else printf("NO\n");
del(root);
}
return 0;
}
二.先输入字典树,再输入其他的字符串,看看是否是前缀的模板
#include <iostream>
#include<cstdlib>
#define MAX 26
using namespace std;
typedef struct TrieNode //Trie结点声明
{
bool isStr; //标记该结点处是否构成单词
struct TrieNode *next[MAX]; //儿子分支
}Trie;
void insert(Trie *root,const char *s) //将单词s插入到字典树中
{
if(root==NULL||*s=='\0')
return;
int i;
Trie *p=root;
while(*s!='\0')
{
if(p->next[*s-'a']==NULL) //如果不存在,则建立结点
{
Trie *temp=(Trie *)malloc(sizeof(Trie));
for(i=0;i<MAX;i++)
{
temp->next[i]=NULL;
}
temp->isStr=false;
p->next[*s-'a']=temp;
}
p=p->next[*s-'a'];
s++;
}
p->isStr=true; //单词结束的地方标记此处可以构成一个单词
}
int search(Trie *root,const char *s) //查找某个单词是否已经存在
{
Trie *p=root;
while(p!=NULL&&*s!='\0')
{
p=p->next[*s-'a'];
s++;
}
return (p!=NULL&&p->isStr==true); //在单词结束处的标记为true时,单词才存在
}
void del(Trie *root) //释放整个字典树占的堆区空间
{
int i;
for(i=0;i<MAX;i++)
{
if(root->next[i]!=NULL)
{
del(root->next[i]);
}
}
free(root);
}
int main(int argc, char *argv[])
{
int i;
int n,m; //n为建立Trie树输入的单词数,m为要查找的单词数
char s[100];
Trie *root= (Trie *)malloc(sizeof(Trie));
for(i=0;i<MAX;i++)
{
root->next[i]=NULL;
}
root->isStr=false;
scanf("%d",&n);
getchar();
for(i=0;i<n;i++) //先建立字典树
{
scanf("%s",s);
insert(root,s);
}
while(scanf("%d",&m)!=EOF)
{
for(i=0;i<m;i++) //查找
{
scanf("%s",s);
if(search(root,s)==1)
printf("YES\n");
else
printf("NO\n");
}
printf("\n");
}
del(root); //释放空间很重要
return 0;
}