------明天開始作線段樹和樹狀數組啦,字典樹先告一段落
《Hat’s Words》就是純粹的字典樹模板啊。。插入完了查找。。只是查找的時候要把每個單詞拆分成所有左右兩部分的組合來查找。
題意:按字典序給出若干個單詞,查找這些單詞裏面是否有這樣的單詞,就是某個單詞是由另外兩個單詞拼接而成的。如果有輸出這個單詞,把滿足條件的這樣的單詞也按字典序輸出。。
思路:把每個單詞都存入字典樹,然後再拆分每個單詞,如果拆分後的兩部分在字典樹中都能查找到,就輸出,因爲輸入是按字典序輸入的。所以輸出時也按順序判斷就好了。
字典樹的意思就是先給一個根節點,然後順着這條根節點往下連接兒子節點的那條邊作爲單詞的一個字母,如果存在這個字母就下去找那個兒子節點,然後同理找下一個字母。不存在這個字母的話,根節點就再生一個兒子,然後繼續不斷地生..查找同理,字母不存在就說明沒這個單詞
本題代碼
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <iostream>
#include <algorithm>
#include <map>
using namespace std;
char a[100];
char b[50010][100];
char c[100];
int ch[50010][26];
int val[50010], tmp;
void insert(char *a)
{
int rt = 0, x;
for (int i = 0; a[i]; i++)
{
x = a[i] - 'a';
if (ch[rt][x] == 0)
{
val[tmp] = 0;
ch[rt][x] = tmp++;
}
rt = ch[rt][x];
}
val[rt] = 1;
}
int find(char *b)
{
int rt = 0, x;
for (int i = 0; b[i]; i++)
{
x = b[i] - 'a';
if (ch[rt][x] == 0)
{
return 0;
}
rt = ch[rt][x];
}
if (val[rt] == 1) return 1;
else return 0;
}
int main()
{
int top = 0;
tmp = 1;
val[0] = 0;
memset(ch[0], 0, sizeof ch);
while (scanf("%s", a) == 1)
{
insert(a);
strcpy(b[top++], a);
}
int i, j, len;
for (i = 0; i < top; i++)
{
len = strlen(b[i]);
for (j = 1; j < len; j++)
{
strcpy(c, b[i]);
c[j] = '\0';
if (find(c) && find(b[i]+j))
{
printf("%s\n", b[i]);
break;
}
}
}
return 0;
}