2007年7月12日木曜日

双数组trie树的基本构造及简单优化

一、 基本构造

Trie树是搜索树的一种,来自英文单词"Retrieval"的简写,可以建立有效的数据检索组织结构,是中文匹配分词算法中词典的一种常见实现。它本质上是一个确定的有限状态自动机(DFA),每个节点代表自动机的一个状态。在词典中这此状态包括"词前缀","已成词"等。

双数组Trie(Double-Array Trie)是trie树的一个简单而有效的实现,由两个整数数组构成,一个是base[],另一个是check[]。设数组下标为i ,如果base[i],check[i]均为0,表示该位置为空。如果base[i]为负值,表示该状态为词语。Check[i]表示该状态的前一状态, t=base[i]+a, check[t]=i 。

下面举例(源自<<双数组Trie(Double-Array Trie)的数据结构与具体实现>>)来说明用双数组Trie(Double-Array Trie)构造分词算法词典的过程。假定词表中只有“啊,阿根廷,阿胶,阿拉伯,阿拉伯人,埃及”这几个词,用Trie树可以表示为:

我们首先对词表中所有出现的10个汉字进行编码:啊-1,阿-2,唉-3,根-4,胶-5,拉-6,及-7,廷-8,伯-9,人-10。。对于每一个汉字,需要确定一个base值,使得对于所有以该汉字开头的词,在双数组中都能放下。例如,现在要确定“阿”字的base值,假设以“阿”开头的词的第二个字序列码依次为a1,a2,a3……an,我们必须找到一个值i,使得base[i+a1],check[i+a1],base[i+a2], check[i+a2]……base[i+an],check[i+an]均为0。一旦找到了这个i,“阿”的base值就确定为i。用这种方法构建双数组Trie(Double-Array Trie),经过四次遍历,将所有的词语放入双数组中,然后还要遍历一遍词表,修改base值。因为我们用负的base值表示该位置为词语。如果状态i对应某一个词,而且Base[i]=0,那么令Base[i]=(-1)*i,如果Base[i]的值不是0,那么令Base[i]=(-1)*Base [i]。得到双数组如下:

下标


1


2


3


4


5


6


7


8


9


10


11


12


13


14

Base


-1


4


4


0


0


0


0


4


-9


4


-11


-12


-4


-14

Check


0


0


0


0


0


0


0


2


2


2


3


8


10


13

词缀























阿根


阿胶


阿拉


埃及


阿根廷


阿拉伯


阿拉伯人

用上述方法生成的双数组,将“啊”,“阿”,“埃”,“阿根”,“阿拉”,“阿胶”,“埃及”,“阿拉伯”,“阿拉伯人”,“阿根廷”均视为状态。每个状态均对应于数组的一个下标。例如设“阿根”的下标为i=8,那么check[i]的内容是“阿”的下标,而base[i]是“阿根廷”的下标的基值。“廷”的序列码为x=8,那么“阿根廷”的下标为base[i]+x=base[8]+8=12。

二、 基本操作与存在问题

1, 查询
trie树的查询过程其实就是一个DFA的状态转移过程,在双数组中实现起来比较简单:只需按照状态标志进行状态转移即可.例如查询“阿根廷”,先根据“阿”的序列码b=2,找到状态“阿”的下标2,再根据“根”的序列码d=4找到“阿根”的下标base[b]+d=8,同时根据 check[base[b]+d]=b,表明“阿根”是某个词的一部分,可以继续查询。然后再找到状态“阿根廷”。它的下标为y=12,此时base [y]<0,check[y]=base[b]+d=8,表明“阿根廷”在词表中,查询完毕。

查询过程中我们可以看到,对于一个词语的查询时间是只与它的长度相关的,也就是说它的时间复杂度为O(1).在汉语中,词语以单字词,双字词居多,超过三字的词语少之又少.因此,用双数组构建的trie树词典查询是理论上中文机械分词中的最快实现。

2, 插入与删除
双数组的缺点在于:构造调整过程中,每个状态都依赖于其他状态,所以当在词典中插入或删除词语的时候,往往需要对双数组结构进行全局调整,灵活性能较差。

将一个词语插入原有的双数组trie树中,相当于对DFA增加一个状态。首先我们应根据查询方法找出该状态本应所处的位置,如果该位置为空,那好办,直接插入即可。如果该位置不为空。那么我们只好按照构造时一样的方法重新扫描得出该状态已存在的最大前缀状态的BASE值,并由此依次得出该状态后继结点的BASE值。在这其中还要注意CHECK值的相应变化。

例如说,如果"阿拉根"某一天也成为了一个词,我们要在trie树中插入这一状态。按计算它的位置应在8,但8是一个已成状态.所以我们得重新确定"阿拉"这一最大已成前缀状态的BASE值.重新扫描得出BASE[10]=11。这样状态15为"阿拉根",且BASE[15]为负(成词), CHECK[15]=10;状态20为"阿拉佰",且BASE[20]=-4,CHECK=10。

这样的处理其实是非常耗时间的,因为得依次对每一个可能BASE值进行扫描来进行确定最大已成前缀状态的BASE值。这个确定过程在构造时还是基本可以忍受的,毕竟你就算用上一,两天来构造也没有问题(只要你构造完后可以在效运行即可)。但在插入比较频繁时,如果每次都需要那么长的运行时间,那确实是无法忍受的。

双数组删除实现比较简单,只需要将删除词语的对应状态设为空即可――即BASE值,CHECK均为设0。但它存在存在一个空间效率的问题.例如,当我们在上面删除"埃及"这一词语时,状态11被设为空。而状态10则成了一个无用结点――它不成词,而且在插入新词时也不可重用。所以,随着删除的进行,空状态点和无用状态点不断增多,空间的利用率会不断的降低。

三、 简单优化

优化的基本思路是将双数组trie树构建为一种动态检索方法,从而解决插入和删除所存在的问题。

1, 插入优化
在插入需要确定新的BASE值时,我们是只需要遍历空状态的。非空状态的出现意味着某个BASE值尝试的打败,我们可以完全不必理会。所以,我们可以对所有的空状态构建一个序列,在确定BASE值时只需要扫描该序列即可。
对双数组中的空状态的递增结点r1,r2, …, rm,我们可以这样构建这一空序列:
CHECK[ri]=−ri+1 (1 i m−1),
CHECK[rm]=−(DA_SIZE+1)
其中r1= E_HEAD,为第一个空值状态对应的索引点。这样我们在确定BASE值时只需扫描这一序列即可。这样就省去了对非空状态的访问时间。

这种方法在空状态并不太多的情况下可以很大程度的提高插入速度。

2, 删除优化
1) 无用结点
对于删除叶结点时产生的无用结点,可以通过依次判断将它们置为空,使得可在插入新词时得以重用。例如,如果我们删除了上例中的"阿根廷",可以看到"阿根"这一状态没有子状态,因此也可将它置为空。而"阿"这一状态不能置空,因为它还有两个子状态。

2) 数组长度的压缩
在删除了一个状态后,数组末尾可能出现的连续空状态我们是可以直接删除的。另外我们还可以重新为最大非空索引点的状态重新确定BASE值,因为它有可能已经由于删除的进行而变小。这们我们可能又得以删除一些空值状态。

20 件のコメント:

精神年齢 さんのコメント...

あなたの精神年齢を占ってみよう!当サイトは、みんなの「精神年齢度」をチェックする性格診断のサイトです。精神年齢度には、期待以上の意外な結果があるかも??興味がある方はぜひどうぞ

逆円助 さんのコメント...

さあ、今夏も新たな出会いを経験してみませんか?当サイトは円助交際の逆、つまり女性が男性を円助する『逆円助交際』を提供します。逆円交際を未経験の方でも気軽に遊べる大人のマッチングシステムです。年齢上限・容姿・経験一切問いません。男性の方は無料で登録して頂けます。貴方も新たな出会いを経験してみませんか

精神年齢 さんのコメント...

みんなの精神年齢を測定できる、メンタル年齢チェッカーで秘められた年齢がズバリわかっちゃう!かわいいあの子も実は精神年齢オバサンということも…合コンや話のネタに一度チャレンジしてみよう

童貞卒業 さんのコメント...

童貞卒業を考えているなら、迷わずココ!今まで童貞とヤッた事がない女性というのは意外と多いものです。そんな彼女たちは一度童貞とやってみたいと考えるのは自然な事と言えるでしょう。当サイトにはそんな好奇心旺盛な女性たちが登録されています

素人 さんのコメント...

癒されたい女性や、寂しい素人女性を心も体も癒してあげるお仕事をご存じですか?女性宅やホテルに行って依頼主の女性とHしてあげるだけで高額の謝礼を手に入れる事が出来るのです。興味のある方は当サイトTOPページをご覧ください

メル友募集 さんのコメント...

最近仕事ばかりで毎日退屈してます。そろそろ恋人欲しいです☆もう夏だし海とか行きたいな♪ k.c.0720@docomo.ne.jp 連絡待ってるよ☆

家出 さんのコメント...

最近TVや雑誌で紹介されている家出掲示板では、全国各地のネットカフェ等を泊り歩いている家出娘のメッセージが多数書き込みされています。彼女たちはお金がないので掲示板で知り合った男性の家にでもすぐに泊まりに行くようです。あなたも書き込みに返事を返してみませんか

動物占い さんのコメント...

あなたの性格を、動物に例えて占っちゃいます。もしかしたらこんな動物かも!?動物占いをうまく使って、楽しい人間関係を築いてください

家出 さんのコメント...

家出中の女性や泊まる所が無い女性達がネットカフェなどで、飲み放題のドリンクで空腹を満たす生活を送っています。当サイトはそんな女性達をサポートしたいという人たちと困っている女性たちの為のサイトです

セレブラブ さんのコメント...

セレブ女性との割り切りお付き合いで大金を稼いでみませんか?女性に癒しと快楽、男性に謝礼とお互い満たしあえる当サイト、セレブラブはあなたの登録をお待ちしております。

夏フェス!! さんのコメント...

夏フェス一緒に行ってくれる人募集!!夏の思い出一緒につくろぉ☆ megumi-0830@docomo.ne.jp 連絡してね♪

無料ゲーム さんのコメント...

あなたのゲーマー度を無料ゲーム感覚で測定します。15個の質問に答えるだけの簡単測定で一度遊んでみませんか?ゲームが得意な人もそうでない人もぜひどうぞ。

素人 さんのコメント...

Hな女性たちは素人ホストを自宅やホテルに呼び、ひとときの癒しを求めていらっしゃいます。当サイトでは男性ホスト様の人員が不足しており、一日3~4人の女性の相手をするホストもおられます。興味を持たれた方は当サイトにぜひお越しください

出会い系 さんのコメント...

実は出会い系には…関係者用入り口があるのを知っていますか?広告主やスポンサー用に用意されたIDではサクラや業者が立ち入ることが出来ないようになっているのです。当サイトでは極秘に入手した関係者用URLが公開されています

逆援助 さんのコメント...

男性はお金、女性は快楽を得る逆援助に興味はありませんか?お金を払っても性的欲求を満たしたいセレブ達との割り切り1日のお付き合いで当サイトでは大金を得ることができます。無料登録なのでアルバイト感覚でOK、詳しくはTOPページでどうぞ。

友達募集 さんのコメント...

ホムペ完成記念!私の事みんなに知ってもらいたくて頑張りましたぁ。色々とご感想をお待ちしているので思った事を意見してください。メアドはほむぺにのせてありますぅ!★ fan.jna@docomo.ne.jp

家出 さんのコメント...

夏休みで気軽に家出する女子○生が急増しています。しかし家出したはいいものの泊る所やお金が無い彼女たちは、掲示板などで泊めてくれる男性を探す子も多いようです。当掲示板にも夏休みに入ってから通常の3倍以上のメッセージが寄せられています

人妻 さんのコメント...

今最もアツイバイトは人妻とのセフレ契約です。当サイトではお金を払ってでもセフレがほしい人妻が集まり、男性会員様との逆援生活を待っています。当サイトで欲求不満の女性との出会いをしてみませんか

素人 さんのコメント...

素人ホストでは、男性のテクニック次第で女性会員様から高額な謝礼がもらえます。欲求不満な人妻や、男性と出会いが無い女性達が当サイトで男性を求めていらっしゃいます。興味のある方はTOPページからどうぞ

友達募集中 さんのコメント...

少し魅惑な自分をネットだから公開してみました。普段言えない事など、思い切って告白しているプロフなので興味ある方はぜひ除いてみてください連絡待ってまぁす。 hinyaaaaa@docomo.ne.jp