#include #include #include using namespace std;
#define max 26
struct node;
typedef struct node *numtree;
struct node
;numtree init(numtree t)
return t;
}void insert(numtree t,char str)
q->ans[id]=s;
q=q->ans[id];
}else
}q->tag=1;
}int find(numtree t,char str)
if(q->tag && ians[id]==null)
q=q->ans[id];
}if(ok && q->tag)
return 1;
}return 0;
}int main()
int u;
for(u=0;u
搞了一下午····
不得不說還是有一些收穫,re的次數最多,
這裡要說一下,re分兩種,一種越界,一種是棧溢位,
這裡在定義str的時候,
如果定義str[50001][100],就會棧溢位,可見字典樹對字元長度的要求很高,不能太長。
整個**的思路就是在insert同時的時候標記,乙個字元如果是乙個字串的結尾字元,那麼標記,
在find的時候,如果找到了乙個標記,找到了a個標記,說明這個字串裡含有a個字串,但無法確定這a個字串是否是緊鄰的,這裡需要用stack或者queue,最好還是用stack,依次記錄有標記的下標,然後從後往前開始查詢,
這裡還有乙個小細節,在查詢的時候now++,因為top回來的now是乙個字元的結尾,重新遍歷的時候應該是從找到標記的字元的後乙個字元開始。
然後如果有兩個以上標記是怎麼回事呢?
如果abcdefg
有三個標記,這時候從最後乙個1開始找,然後從倒數第二個1找,而這裡的1代表,至少字典裡有a,abcd,abcdefg三個字串(也可能有defg,bcd等等),也就是說我從標記的下乙個字元開始找起,標記的前半部分已經肯定在字串裡了(也就是組成該字串的前半段),只需要證明從標記開始的字串也在字典樹里,那麼就滿足該字串由兩個字串構成,輸出即可。
這題還有乙個思路,就是把每乙個字串在不同位置「砍一刀」,變成兩個字串,然後find(str1)find(str2),如果都能找到,那麼就說明它(這個字串)有兩個字串構成,這個**我也實現了,但是不知道為什麼一直re,可能是迭代或者遞迴的層數太多了(find要遞迴,如果字串很長的話,也要砍很多刀)。暫時我還沒有想到比較好的優化方案。砍刀也許可以用二分查詢實現,但那仍然依賴輸入。對效率提公升不一定十分明顯。
#include #include using namespace std;
#define max 26
struct node;
typedef struct node *numtree;
struct node
;numtree init(numtree t)
void insert(numtree t,char str)
else
}}int find(numtree t,char str)
}return tag;
}void freetree(numtree t)
free(t);
}int main()
int u;
for(u=0;u
hdu1247 字典樹模板
今天又接觸了乙個樹 字典樹。給出結構圖。其優點 節約儲存空間,提高查詢效率。其主要函式用法insert 插入結點,用到了指標,總感覺指標用在表示前字尾這種關係上是最清晰的了。先把這份模擬別人寫的 寫下當作模板!以後有時間再繼續做幾道字典樹的題。include include includeusing...
HDU1247 字典樹經典題
題意 給你一些單詞,問你其中哪乙個單詞可以由其他兩個單詞組成,還有就是乙個單詞可以由同乙個單詞重複組成兩次。題解 把乙個單詞拆分成兩個進去find函式查詢,如果兩個都可以說明該單詞由兩個單詞組成。include include include using namespace std const in...
單詞數 HDU 2072 字典樹
hdu 2072 lily的好朋友xiaoou333最近很空,他想了一件沒有什麼意義的事情,就是統計一篇文章裡不同單詞的總數。下面你的任務是幫助xiaoou333解決這個問題。input 有多組資料,每組一行,每組就是一篇小文章。每篇小文章都是由小寫字母和空格組成,沒有標點符號,遇到 時表示輸入結束...