题意
给定输入的n个电话号码,判断有没有某个号码是另一个的前缀。
很明显的字典树的应用,在模板上稍微修改即可:
代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 10
struct Trie{
Trie *next[MAX]; //分支数
int v;//以当前字符串为前缀的个数
};
Trie *root;
int T,n,flag;
void InitRoot()
{//初始化root 节点,以及一些全局变量
root=(Trie*)malloc(sizeof(Trie));
flag=0;
for(int i=0; i<MAX; i++)
{
root->next[i]=NULL;
}
}
void createTrie(char *str)
{//建立树
Trie *p=root, *q;
for(int i=0; i<strlen(str); i++)
{
int id=str[i]-'0';
if(p->next[id])
{//之前存在了前缀
p->next[id]->v++;//更新计数
p=p->next[id];
}
else
{
q=(Trie*)malloc(sizeof(Trie));//新建节点
q->v=1;
for(int i=0; i<MAX; i++)
q->next[i]=NULL;
p->next[id]=q;
p=q;
}
}
p->v=-1;//叶子节点标志
}
int findTrie(char *str)
{//查找
Trie *p=root;
for(int i=0; i<strlen(str); i++)
{
int id =str[i]-'0';
p=p->next[id];
if(!p) return 0;// 到结尾
if (p->v==-1) return -1;//
}
return -1;
}
void del(Trie *T)
{//删除树
for(int i=0;i<MAX; i++)
{
if(T->next[i]) del(T->next[i]);
}
free(T);
}
int main()
{
char str[11];
scanf("%d",&T);
while(T--)
{
InitRoot();
scanf("%d",&n);
for(int i=0;i<n; i++)
{
scanf("%s",str);
if(findTrie(str)==-1)
{//存在前缀
flag=1;
continue;
}
createTrie(str);//否则 对Trie树 加入新的节点
}
flag?printf("NO\n"):printf("YES\n");
del(root);
}
}