hdu 2846 Repository

weixin_34037977發表於2017-06-14
題意:
     給你一些模式串。然後給你一些提問,每一個提問是給你一個串,問你這個串在上
面的模式串中出現的次數。


思路:

    字典樹處理字首的出現的次數的時候很拿手的,對於這個題目。我們能夠把每一個串都拆開。拆成一個一個的,然後在把他們加在樹裡面,這樣就OK了,另一個關鍵的地方,就是比方拆這個串 aa 能夠拆成 a ,a ,aa。所以我們要在第一個a的時候僅僅累加一次,怎麼做到呢,能夠在node的結構體裡面在開個變數,標記當前這個字母最後一次是被誰更新的,假設是自己,那麼就不會num++.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define ZERO 0
#define ALPH_LEN 26 /* 26個字母 */
const char FIRST_CHAR = 'a';

typedef struct node
{
    struct node *child[ALPH_LEN]; /* 儲存下一個字元 */
    int n;
    int  num;
}node, *Node;

Node root; /* 字典樹的根結點(不儲存不論什麼字元) */
/* 插入單詞 */
void insert(char *str,int k)
{
    int i, index, len;
    Node current = NULL, newnode = NULL;
    
    len = strlen(str);
    
    current = root; /* 開始時當前的結點為根結點 */
    for (i = 0; i < len; i++) /* 逐個字元插入 */
    {
        index = str[i] - FIRST_CHAR; /* 獲取此字元的下標 */
        if (current->child[index] != NULL) /* 字元已在字典樹中 */
        {
            current = current->child[index]; /* 改動當前的結點位置 */
            if(current->num!=k)
            {
               (current->n)++;
               current->num=k;
            } 
        }
        else /* 此字元還沒出現過, 則新增結點 */
        {
            newnode = (Node)calloc(1, sizeof(node)); /* 新增一結點, 並初始化 */
            current->child[index] = newnode;
            current = newnode; /* 改動當前的結點的位置 */
            current->n = 1; /* 此新單詞出現一次 */
            current->num=k;
        }
    }
}
/* 在字典樹中查詢單詞 */
int find_word(char *str)
{
    int i, index, len;
    Node current = NULL;
    
    len = strlen(str);
    
    current = root; /* 查詢從根結點開始 */
    for (i = 0; i < len; i++)
    {
        index = str[i] - FIRST_CHAR; /* 獲取此字元的下標 */
        if (current->child[index] != NULL) /* 當前字元存在字典樹中 */
        {
            current = current->child[index]; /* 改動當前結點的位置 */
        }
        else
        {
            return ZERO; /*還沒比較完就出現不匹配, 字典樹中沒有此單詞*/
        }
    }
    
    return current->n; /* 此單詞出現的次數 */
}

int main()
{
    char str[25],str2[25];
    int i,n,m,j,len;
    
    root = (Node)calloc(1, sizeof(node));
    scanf("%d",&n);
   {
      for(i=1;i<=n;i++)
      {
         scanf("%s",str);
         len=strlen(str);
        for(j=0;j<len;j++)
       {
          
          strncpy(str2,str+j,len-j);
          str2[len-j]='\0';
          insert( str2, i );
        }
      }
      scanf("%d",&m);
      while(m--)
      {
        scanf("%s",str);
        i = find_word( str );
        printf("%d\n", i);
      }
   }
    return 0;
}


相關文章