程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> HDU 2846 Repository

HDU 2846 Repository

編輯:C++入門知識

Repository Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 1750    Accepted Submission(s): 651     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 2009 Multi-University Training Contest 4 - Host by HDU     Recommend gaojie  解題思路:字典樹第三彈,這一題要求我們找到輸入的詞是字典中多少個詞的子串,而不僅僅是其前綴,因此建樹的時候需要將詞典中詞分解成不同前綴加入到樹中,即是說將形如abc的詞拆成abc,bc,c,三種形式,這樣就相當於找輸入的詞是詞典中多少詞的前綴,需要注意的是,對於同一個詞分解出的多個前綴,如果他們之間有相同的話,這種前綴,只算作一種,即是說形如abca之類的詞,會分解出abca,a兩種前綴,但因為是同一個詞分解出來的,所以算作一種。判斷是否是同一個詞分解出來的需要給每個輸入的詞及其分解出的前綴加以相同的id進行編號。 [cpp]   #include<cstdio>   #include<cstring>   #include<iostream>   using namespace std;   int ans,len;   typedef struct TrieNode   {       int c,id;       struct TrieNode *next[26];       TrieNode()       {           id=-1;//初始化每個節點的id為-1           c=0;           memset(next,0,sizeof(next));       }   };      TrieNode *root=NULL;   void CreatTree(char s[],int num)   {       int i,len;       len=strlen(s);       TrieNode *p=root;       TrieNode *temp;       for(i=0;i<len;i++)       {    www.2cto.com         if(p->next[s[i]-'a']==NULL)           {               temp=new TrieNode;               p->next[s[i]-'a']=temp;           }           p=p->next[s[i]-'a'];           if(p->id!=num)//如果分解出的詞的前綴與已經在之前分解的詞的前綴相同(id==num),那就不能算作一種新的前綴              p->c++;           p->id=num;//對同一個詞分解出的詞,在樹上的各個節點給予相同id       }   }   void Search(char s[],int d)   {       int i,j;       TrieNode *p=root;       for(i=0;i<d;i++)       {           if(p->next[s[i]-'a'])               p=p->next[s[i]-'a'];           else           {               ans=0;//如果輸入的詞不是詞典中任何詞及其分解出的詞的前綴,那這個詞就不是詞典中任何一個詞的子串               return;           }       }       ans=p->c;//否則,在不同詞的分解的詞(重復的不算)中,輸出的詞是多少個詞的前綴就是所求答案   }   void Delete(TrieNode *node)   {       int i;       for(i=0;i<26;i++)       {           if(node->next[i])               Delete(node->next[i]);           delete node->next[i];           node->next[i]=0;       }   }   int main()   {       int i,j,m,n,len;       char str[25],temp[25];       root=new TrieNode;       scanf("%d",&n);       memset(str,'\0',sizeof(str));       for(i=0;i<n;i++)       {           scanf("%s",&str);           len=strlen(str);           for(j=0;j<len;j++)           {               strncpy(temp,str+j,len-j);//將詞典中詞以不同前綴進行分解,並分別加入樹中               temp[len-j]='\0';               CreatTree(temp,i);//i用以判斷是否為詞典中同一個詞分解出來的           }           memset(str,'\0',sizeof(str));       }       scanf("%d",&m);       for(i=0;i<m;i++)       {   www.2cto.com         ans=0;           scanf("%s",&str);           len=strlen(str);           Search(str,len);           printf("%d\n",ans);       }       Delete(root);       return 0;   }    

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved