zoukankan      html  css  js  c++  java
  • POJ2001 Shortest Prefixes 用trie树实现

    题目:
    问你最短能构成前缀的且不包括已有的单词(当没有时为自己)的单词
    分析:
    用trie树做,动态构树,然后从根节点开始往下找,当找到之前是已经有单词
    或者该处的单词已经走过该节点,继续往下,直到这两个条件不成立为止

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    using namespace std;
    struct trie
    { //trie树
    bool haveword;//标记是否已有树
    int num; //表示到目前为止单词走过该节点的单词数
    trie *p[26];
    trie()
    {
    haveword = false;
    num = 0;
    memset(p,NULL,sizeof(p));
    }
    }root;
    void insert(trie *r,char *s)
    { //节点插入函数,动态构树
    for(int i=0;s[i];i++)
    {
    if(r->p[s[i]-'a']==NULL)//为空时
    r->p[s[i]-'a'] = new trie();
    else //不为空时,即已有其它单词用过之前的路径
    r->p[s[i]-'a']->num++;//给该节点数标记加一
    r = r->p[s[i]-'a']; //调到下一个节点
    }
    r->haveword = true;
    }
    void find(trie *r,char *s)
    { //查找函数
    char print[22];//最后输出的最短路径的单词
    int cnt = 0;
    for(int i=0;s[i];i++)//从根部开始往下搜
    {
    int c = s[i]-'a';
    if(r->p[c]->haveword||r->p[c]->num)//如果该节点已有单词在此结尾或者有其它单词用过之前的路径
    print[cnt++] = s[i];
    else //否则的话,此处到根就是最短的路径
    {
    print[cnt++] = s[i];
    break;
    }
    r = r->p[c];
    }
    for(int i=0;i<cnt;i++)//输出
    printf("%c",print[i]);
    printf("\n");
    }
    int main()
    {
    freopen("sum.in","r",stdin);
    freopen("sum.out","w",stdout);
    char ch[1001][22];//记录输入的单词
    int cnt = 0;
    trie *r = &root;//构造的树
    while(scanf("%s",ch[cnt])!=EOF)
    insert(r,ch[cnt++]); //把输入的单词插入到字典树中
    for(int i=0;i<cnt;i++)//查找函数
    {
    printf("%s ",ch[i]);
    find(r,ch[i]);
    }
    return 0;
    }

  • 相关阅读:
    利用哈希map快速判断两个数组的交集
    TCP协议中的三次握手和四次挥手(图解)-转
    PC,移动端H5实现实现小球加入购物车效果
    HQL和SQL的区别
    Java泛型详解,通俗易懂只需5分钟
    经典的 Fork 炸弹解析
    Java并发之AQS详解
    Java不可重入锁和可重入锁的简单理解
    Codeforces 1215F. Radio Stations
    Codeforces 1215E. Marbles
  • 原文地址:https://www.cnblogs.com/yejinru/p/2374674.html
Copyright © 2011-2022 走看看