2011-02-09 13 views
2

背景:ファイルシステムの辞書から定義(科学)を検索するWindows Mobile用のC#アプリケーションを作成しています。ユーザーが単語を入力して、できるだけ速く意味を得ることができる必要がありファイル内のキーへの高速アクセス(ファイル全体をメモリにロードせずに)

Word1:Meanings(2) 
-meaning 1 bla bla bla 
-meading 2 bla bla bla 
[...] 

: ファイルは、この(ファイルが100K +のエントリを持っている)のように見えます。ユーザーは1語または2語のみを検索します。これを行うには、私はソートされたリストで実際の単語とバイトオフセットの辞書ファイルで2番目のファイルを作成しました。 例:

word1:12344 
word2:32241 
word3:298 

私は(すべてのラインを介して単純なループと等しい場合の比較)私の「インデックス」に目を通した後、「ランダム・アクセス」のバイト・オフセットを使用して辞書ファイル。 問題は、これはまだ遅いです。 インデックスを配列/リスト/ハッシュテーブルにロードしようとしましたが、遅いioのために、これは時間がかかりすぎて(インデックスのロードに約20秒かかる)。これは、ユーザーが一般的に1語だけを検索するため、悪いことです。 したがって、(インデックス全体を走査することなく)ファイル上で直接動作できるいくつかのタイプのn-tree実装を探しています。 誰かがこれを行う方法をアドバイスしていますか? 新しいインデックスはこの形式になっています:

a:FileOffsetInDictionary:FileOffsetOf"ab" //the first 2 character starting with a 
b:FileOffsetInDictionary:FileOffsetOf"ba" 
c:FileOffsetInDictionary:0 //"0" means that their are no words starting with "c" (just for example) 
[...] 
ab:FileOffsetInDictionary:FileOffsetOf"aba" 
ac:FileOffsetInDictionary:878878 //(just some random values for illustration) 
[...] 
ba:FileOffsetInDictionary:456 
[...] 
aba:FileOffsetInDictionary:2342 
[...] 

と検索このように行われる:

Users enter the word "Tree" 
Look for "t" in index by looping through the index 
if "t" found then goto FileOffsetOf2Digit 
if "tr" found then goto FileOffsetOf3Digit 
[...] 
[actually recursively coded] 
+5

基本的にデータベースへのインデックス付きアクセスを再実装しています。 SQL Server CEなど、実際のデータベースをタスクに使用することを検討しましたか?これは、Windows Mobile上で正常に動作するファイルベースのデータベースシステムであり、アプリケーションに少数の(小さな)DLLを含める必要があります。 – Heinzi

+0

@Heinziご回答ありがとうございます。それが本当のビジネスアプリケーションであれば、私はSQLデータベースを使用します。しかし、私はコンピュータサイエンスが大好きで、通常のSQLデータベースより速いものを書こうと思っていました:)現在の目標は、各キーストロークの後に結果を表示することです( "tre"は "tree"、 "trends"の結果を表示する必要があります) – justin

+0

ファイルから読み取るコード?それは我々が助けることができるいくつかのパフォーマンス上の問題を有するかもしれない。 – user7116

答えて

1

を正しい答えは、おそらくになり 私の現在のソリューションは、この(ただし、バギーや汚れが)のように見えますこの性質のディスクベースのインデックスには理想的なb-treeインデックスを使用するように指示するか、モバイル6.5以前についてはSQL CEデータベースを使用する方がよいでしょう。そして、あなたはいくつかの実装を見つけることができますが、次のことができない場合は失敗します。

現在のインデックスファイルのアイデアの行に沿って何かを使用して、各インデックスレコードを固定サイズにします。したがって、単語が50文字以上にならず、オフセットが4バイトの整数に収まることがわかっている場合は、インデックスファイルに54バイトのレコードエントリを作成することができます。その後、ファイル全体をスキャンして各レコードにアクセスするのではなく、インデックスファイルに対してbinary searchを実行することができます。

+0

ありがとう!私はどのようにディスク(ファイル)から直接bツリーにアクセスするのか分かりません。私は長い間かかるので、メモリ内にbツリーを構築したくありません。私は固定フィールド+私の問題のバイナリ検索をベンチマークします。 – justin

1

これを自分で実装する必要がある場合は、コーパス全体のtrieを作成する必要があります。これは、既知のデータのBツリー、Red-Blackツリー、またはハッシュテーブルよりも高速で、部分一致を保存できます。私。それを "T"と呼ぶと、あなたのコーパスの文字 "T"の最初のインスタンスを返します。それを "r"で呼び出して "T"の最初のインスタンスを指定すると、最初に "T"を検索することなくコーパス内の "Tr"の最初のインスタンスを返します。

+0

実際、私の新しいインデックスはちょっとトライを作ろうとしています。私はインターネット上で多くを検索し、メモリ内の試行しか見つけられませんでした。 「通常の」ファイルでトライをどのように表現するかについてのリソースはありますか? – justin

+0

私はメモリ試しだけを使用しました。通常は参照の局所性が低く、ディスクアクセスには適していません。私はHATがこれに対処しようとしていると聞いています。http://crpit.com/confpapers/CRPITV62Askitis.pdfをチェックしてください。 –

関連する問題