nyoj163 Phone List

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream> 
 4 using namespace std;
 5 struct node{
 6     node *next[10];
 7     int end;
 8     node(){  //构造函数,方便初始化数据 
 9         memset(next,NULL,sizeof(next));
10         end=0;  //end=0表示一般节点,end=1标志一个电话号的结束 
11     }
12 };
13 node *root;
14 bool insert(char *s)
15 {
16     int i,k,flag;
17     node *p=root;
18     for(flag=i=0;s[i];++i){
19         k=s[i]-'0';
20         if(p->next[k]==NULL){
21             p->next[k]=new node();
22             flag=1;   //标记建立过一个新节点 
23         } 
24         p=p->next[k];
25         if(p->end) return 0; //碰到结束标志,则返回0 
26     }
27     p->end=1;  //一个电话号的结束标志 
28     if(!flag) return 0;//字符串插入完毕未出现新建节点的操作,返回0 
29     return 1;
30 }
31 int del(node *p)  //释放字典树空间,否则占用空间太大 
32 {  
33     if(p==NULL) return 0;
34     for(int i=0;i<10;i++)
35         if(p->next[i]) del(p->next[i]);
36     delete p;
37     return 0;
38 } 
39 int main()
40 {
41     int n,T;
42     char s[11];
43     scanf("%d",&T);
44     while(T--){
45         bool flag=1;
46         root=new node();
47         scanf("%d",&n);
48         while(n--){
49             scanf("%s",s);
50             if(flag) flag=insert(s);//假如出现过混乱情况,则不再进行插入操作 
51         }
52         del(root);
53         if(flag) puts("YES");
54         else puts("NO");
55     }
56     return 0;
57 }

如果字符串Xn=X1X2....Xn是字符串Ym=Y1Y2....Ym的前缀,有在插入的时候有两种情况:Xn在Yn之前插入,Xn在Yn之后插入。

 (1)如果Xn在Yn之前插入,那么在插入Yn的时候必然经过Xn的路径,此时可以根据判断在这条路径上是否已经有结点被标记已经构成完成的字符串序列来判断是否存在Yn的前缀;

(2)如果Xn在Yn之后插入,那么插入完成之后当前指针指向的结点的next数组中的元素必定不全为NULL。

转载于:https://www.cnblogs.com/shihuajie/archive/2012/08/09/2629553.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值