zoukankan      html  css  js  c++  java
  • HDU2846 Repository(字典树)

    Repository

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
    Total Submission(s): 5761    Accepted Submission(s): 1911


    Problem Description
    When you go shopping, you can search in repository for avalible merchandises by the computers and internet. First you give the search system a name about something, then the system responds with the results. Now you are given a lot merchandise names in repository and some queries, and required to simulate the process.
     
    Input
    There is only one case. First there is an integer P (1<=P<=10000)representing the number of the merchanidse names in the repository. The next P lines each contain a string (it's length isn't beyond 20,and all the letters are lowercase).Then there is an integer Q(1<=Q<=100000) representing the number of the queries. The next Q lines each contains a string(the same limitation as foregoing descriptions) as the searching condition.
     
    Output
    For each query, you just output the number of the merchandises, whose names contain the search string as their substrings.
     
    Sample Input
    20 ad ae af ag ah ai aj ak al ads add ade adf adg adh adi adj adk adl aes 5 b a d ad s
     
    Sample Output
    0 20 11 11 2
     
    Source
     
    Recommend
    gaojie   |   We have carefully selected several similar problems for you:  2852 2847 2845 2850 2851 
     
    题意 先给出 n个字符串,  再给出m个询问,每个询问给出一个字符串,问在先前的n个字符串中以它为子串的字符串有多少个
     
    分析:普通字典树用来判断前缀的数量,所以在这里不能直接建树.那么如果把字符串的每个后缀都建树,那么现在的所有的前缀就相当于字符串的所有子串了.
             但是这样会出现一个问题,比如abab 在计算以ab为子串的字符串的时候会被统计两次,所以我们需要对同一个字符串中的后缀在建树的时候进行标记
            代码如下:
    #include <cstdio>
    #include <iostream>
    #include <cstring>
    using namespace std;
    const int MAXN=26;  //只有小写字母
    typedef struct Trie{
       int v;
       int num; //进行标记
       Trie *next[MAXN];
    }Trie;
    Trie *root;
    char r[100];
    void createTrie(char *str,int k)
    {
        int len=strlen(str);
        Trie *p=root,*q;
        for(int i=0;i<len;i++)
        {
         int id=str[i]-'a';
         if(p->next[id]==NULL)
         {
             q=(Trie*)malloc(sizeof(Trie));
             q->num=k;  //将后缀的每一部分都标记
             q->v=1;              //每次建立新节点进行初始化操作
             for(int j=0;j<MAXN;j++)
                q->next[j]=NULL;
             p->next[id]=q;
             p=p->next[id];
         }
         else
         {
              if(p->next[id]->num!=k){
             p->next[id]->v++;   //如果和标记不相等,代表不是同一字符串,才进行计数
             p->next[id]->num=k;
              }
             p=p->next[id];
         }
        }
    }
    int findTrie(char *str)
    {
        int len=strlen(str);
        Trie *p=root;
        for(int i=0;i<len;i++)
        {
            int id=str[i]-'a';
            p=p->next[id];
            if(p==NULL)
                return 0;
        }
        return p->v;
    }
    int  deal(Trie *T)
    {
        int i;
        if(T==NULL)
            return 0;
        for(int i=0;i<MAXN;i++)
        {
            if(T->next[i]!=NULL)
                deal(T->next[i]);
        }
        free(T);
        return 0;
    }
    int main()
    {
        char str[21];
        char s[100];
        int t,n,flag,cnt,m;
        root=(Trie*)malloc(sizeof(Trie));
        for(int i=0;i<MAXN;i++)
          root->next[i]=NULL;
          root->v=false; //初始化
          scanf("%d",&n);
           for(int i=0;i<n;i++)
          {
              scanf("%s",str);
             int len=strlen(str);
             for(int j=0;j<len;j++){
                for(int k=j;k<len;k++)
             {
                 r[k-j]=str[k];
             }
                r[len-j]='';
                createTrie(r,i);
             }
          }
          scanf("%d",&m);
          for(int i=0;i<m;i++)
          {
              scanf("%s",s);
              printf("%d
    ",findTrie(s));
          }
        //deal(root);
        return 0;
    }

    还需要注意的是,在这个题,每个字符数组都只使用一次,所以不用开二维数组进行记录

     
  • 相关阅读:
    上标<sup>与下标<sub>
    Java7基础教程 Jay Bryant著 李鹏 韩智译
    Error:Could not find com.android.tools.build:gradle:2.14.1.
    nginx-rtmp-module安装笔记
    Page Scroll using Selenium WebDriver
    个人家庭宽带搭建多域名web网站服务器配置
    phpmyadmin mysql Access denied for user 'root'@'localhost'问题解决
    sizeWithFont 取消后
    根据size截取图片中间矩形区域的图片 这里的size是正方形
    给UIImageView添加点击事件
  • 原文地址:https://www.cnblogs.com/a249189046/p/7469533.html
Copyright © 2011-2022 走看看