題意:
給你一些模式串。然後給你一些提問,每一個提問是給你一個串,問你這個串在上
面的模式串中出現的次數。
給你一些模式串。然後給你一些提問,每一個提問是給你一個串,問你這個串在上
面的模式串中出現的次數。
思路:
字典樹處理字首的出現的次數的時候很拿手的,對於這個題目。我們能夠把每一個串都拆開。拆成一個一個的,然後在把他們加在樹裡面,這樣就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;
}