• POJ 2001 Shortest Prefixes 【Trie树】


    <题目链接>

    题目大意:

    找出能唯一标示一个字符串的最短前缀,如果找不出,就输出该字符串。

    解题分析:

    Trie树的简单应用,对于每个单词的插入,都在相应字符对应的节点 num 值+1 ,这样在查询的时候,如果遍历到num值为1的节点,就可以确定,该前缀能够唯一确定一个字符串,或者是一直遍历到NULL,这时直接输出它本身即可。

    指针式Trie树:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 using namespace std;
     5 
     6 const int N =1e3+10;
     7 char word[N][26];
     8 struct Node{
     9     int num;
    10     Node *next[26];
    11     Node(){
    12         num=0;
    13         for(int i=0;i<26;i++)
    14             next[i]=NULL;
    15     }
    16 };
    17 Node *root;
    18 Node *now,*newnode;
    19 void Insert(char *str){
    20     now=root;
    21     for(int i=0;i<strlen(str);i++){
    22         int to=str[i]-'a';
    23         if(now->next[to]==NULL){   //如果该节点为空
    24             newnode=new Node;
    25             ++(newnode->num);
    26             now->next[to]=newnode;
    27             now=now->next[to];
    28         }
    29         else{
    30             now=now->next[to];   
    31             ++(now->num);
    32         }
    33     }
    34 }
    35 void Search(char *str){
    36     char ans[26];
    37     now=root;
    38     for(int i=0;i<strlen(str);i++){
    39         int to=str[i]-'a';
    40         now=now->next[to];
    41         ans[i]=str[i];    //ans[]记录下前缀字符串
    42         ans[i+1]='';
    43         if(now->num==1){    //如果该节点只有一个对应的公共前缀,那么就是它本身的前缀,所以直接输出该节点的对应前缀即可
    44             printf("%s %s
    ",str,ans);
    45             return;
    46         }
    47     }
    48     printf("%s %s
    ",str,str);    
    49 }
    50 int main(){
    51     root=new Node;
    52     int cnt=0;
    53     while(gets(word[++cnt])){
    54         //if(!strlen(word[cnt]))break;
    55         Insert(word[cnt]);
    56     }
    57     for(int i=1;i<=cnt;i++)Search(word[i]);
    58     return 0;
    59 }

    数组式Trie树        转载于   >>>

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 using namespace std;
     5 char a[10001][31];
     6 int tot,size;
     7 int sz,t[300001][26],s[300001];
     8 void insert(char ch[])
     9 {
    10     int k,len=strlen(ch+1),now=0;
    11     for(int p=1;p<=len;p++)
    12     {
    13           k=ch[p]-'a';
    14           if(t[now][k]==0)t[now][k]=++sz;
    15         now=t[now][k];
    16         s[now]++;
    17     }
    18 }
    19 void ask(char ch[])
    20 {
    21     int now=0,k,len=strlen(ch+1);
    22     for(int p=1;p<=len;p++)
    23     {
    24         if(s[now]==1)break;
    25         k=ch[p]-'a';
    26         printf("%c",ch[p]);
    27         now=t[now][k];
    28    }
    29 }
    30 int main()
    31 {
    32     while(scanf("%s",a[++tot]+1)!=EOF)insert(a[tot]);
    33     for(int i=1;i<=tot;i++)
    34     {
    35         printf("%s ",a[i]+1);
    36         ask(a[i]);
    37         printf("
    ");
    38     }
    39     return 0;
    40 }

    2018-10-29

  • 相关阅读:
    C# 2.0 中Iterators的改进与实现原理浅析
    C#窗口关闭时最小化到托盘
    设计模式有趣解释
    序列化学习
    线程学习
    正则表达式
    .net内存回收与Dispose﹐Close﹐Finalize方法 [摘]
    5.匿名函数lambda
    2dns服务器解析创建
    2.ftp匿名
  • 原文地址:https://www.cnblogs.com/00isok/p/9870037.html
Copyright © 2020-2023  润新知