關於學習字典樹,可以轉步這篇文章傳送門
例題1、poj3630 / hdu 1671
這裡要在插入時候進行檢驗是否存在某個號碼是已存在號碼的字首或者存在某個號碼是當前插入號碼
的字首。
先說hdu1671,因為poj的使用動態建樹給tle了,所以要用靜態建樹,這裡先說動態建樹
hdu1671 **(感覺可以做模板)
#include
#include
#include
#include
#include
#include
#include
#include
using
namespace std;
const
int size =10;
struct trie
;void
init
(trie *node)
trie *root =
new trie;
//建立根節點;
bool
insert
(char s)
p = p-
>next[pos]
; p-
>count++;if
(p->count >
1&&p-
>isend)
} p-
>isend =
true
;//表明當前位置為乙個單詞的節點
if(p-
>count >
1&&p-
>isend)
return
true;}
intsearch
(char s)
p = p-
>next[pos];}
return p-
>count;
//如果經過這裡的次數 > 0就說明這個單詞存在
}//清除trie
void
del(trie *root,
int mark)}if
(mark)
}//遍歷
/*void print(trie *root)
}}*/int
main()
}}if(flag)
else
del(root,0)
;//釋放樹,下次再建立
}return0;
}
下面說一下靜態建樹
其實就是把空間提前分配好,然後把分配好空間的位址在程式需要往下建樹的時候傳過去就可以,就是多了乙個靜態陣列和乙個傳遞當前陣列元素位址的函式
剩下的跟動態建樹一樣操作
**如下
#include
#include
#include
#include
#include
#include
#include
#include
using
namespace std;
const
int size =10;
const
int maxn =
100000
+999
;struct trie
trie[maxn]
;int cnt =0;
//傳遞陣列元素位址,算是模擬分配空間吧,只不過是空間提前分配好了,把位址傳進去而已
trie *
newnode()
void
init
(trie *node)
trie *root =
newnode()
;//建立根節點;
bool
insert
(char s)
p = p-
>next[pos]
; p-
>count++;if
(p->count >
1&&p-
>isend)
} p-
>isend =
true
;//表明當前位置為乙個單詞的節點
if(p-
>count >
1&&p-
>isend)
return
true;}
intsearch
(char s)
p = p-
>next[pos];}
return p-
>count;
//如果經過這裡的次數 > 0就說明這個單詞存在
}//清除trie
void
del(trie *root,
int mark)}if
(mark)
}//遍歷
/*void print(trie *root)
}}*/int
main()
}}if(flag)
else
//del(root,0);//釋放樹,下次再建立
memset
(trie,0,
sizeof trie)
;//將空間清0
}return0;
}
2、poj2001
就不說題意了
就是先把樹建好,設定乙個count記錄字首被經歷了幾次,如果出現一次,那麼就直接把這個字首輸出,反之就繼續向下輸出字首,最壞的結果就是把整個字串輸出。
**
#include
#include
#include
#include
#include
#include
#include
#include
using
namespace std;
const
int size =26;
const
int maxm =
100000
+999
;const
int maxn =
100005
;struct trie
trie[maxm]
;int cnt;
char s[
1005][
25];//傳遞陣列元素位址,算是模擬分配空間吧,只不過是空間提前分配好了,把位址傳進去而已
trie *
newnode()
trie *root =
newnode()
;//建立根節點;
void
init
(trie *node)
void
insert
(const
char
*s) p = p-
>next[pos]
; p-
>count++;}
p->isend =
true
;//表明當前位置為乙個單詞的節點
}int
search
(const
char
*s) p = p-
>next[pos];}
return p-
>count;
//如果經過這裡的次數 > 0就說明這個單詞存在
}//清除trie
void
del(trie *root,
int mark)}if
(mark)
}//遍歷
/*void print(trie *root)
}}*/void
output
(const
char
*s) p = p-
>next[pos];}
}int
main()
for(
int i =
0; i < cot; i++
)return0;
}
字典樹 例題
給定 n個長度不超過10的數字串,問其中是否存在兩個數字串 s t,使得 s是 t的字首,多組資料。輸入格式 第一行乙個整數 t,表示資料組數。對於每組資料,第一行乙個數n,接下來 n行輸入 n個數字串。輸出格式 對於每組資料,若存在兩個數字串 s t,使得 s是 t的字首,則輸出 no 否則輸出 ...
Trie字典樹例題
前幾天做了個trie樹的題,正好記一下。首先先看乙個簡單題 acwing 143.最大異或對 題目 在給定的n個整數a1,a2 an中選出兩個進行 xor 異或 運算,得到的結果最大是多少?第一行輸入乙個整數n。第二行輸入n個整數a1 an。輸出乙個整數表示答案。1 n 105 0 a i 23 1...
字典樹入門和例題
如圖所示 每個字元有很多個分支,打黃色標記的就是字串的結尾,所以這顆字典樹中有哪些字串呢,ab ay ayf c cc cd 其他的枝沒有畫全。順序儲存字串 ab ay ayf c cc cd 節點編號講究先到先得 陣列tree i j 代表i 節點的第 j個兒子的節點編號。獲取第幾個孩子可以s i...