文字列を登録して、その文字が存在するかどうかを調べる場合、ハッシュやブルームフィルターなどが考えられる。
しかし、ハッシュは衝突が頻繁におこると最悪計算量がO(N)まで悪化する。(Nはキーの数。)
ブルームフィルターは高速に登録、判定ができるが、擬陽性があるため厳密なチェックに使うには抵抗がある。
Trie木は、論理上ハッシュと同等の速度で文字列処理ができ(実際はTrie木の方が速い)、ブルームフィルターのような偽検出もない。
ということで、Trie木を使いましょう。
Spaghetti sourceに実装があります。
短くてシンプルだけど、凡人の私には理解するのに少し時間がかかりました。。(汗)
自分でかいたソースは以下。
- class Trie {
- public:
- Trie *next[26];
- Trie () {
- fill(next, next+26, (Trie *)0);
- }
- void insert(char *s) {
- if (*s == '\0') return;
- if (this->next[*s-'a'] == NULL)
- this->next[*s-'a'] = new Trie();
- this->next[*s-'a']->insert(s+1);
- }
- bool find(char *s) {
- if (*s == '\0') return true;
- if (this->next[*s-'a'] == NULL)
- return false;
- return this->next[*s-'a']->find(s+1);
- }
- };
0 件のコメント:
コメントを投稿