2011-02-09 6 views
4

大きな本のように巨大な文字列内の文字列の出現回数を見つける方法:どのように効率的に単語の出現回数内を見つけるだろう私は最近、C#のインタビューセッション中にこの質問をした

大きな本のような巨大なテキスト(聖書、辞書など)。

この本の内容を格納する最も効率的なデータ構造は何でしょうか。私が考えることができるもっとも汚いのは、StringBuilderに格納して部分文字列の数を調べることでしたが、これを行うにはより良い方法が必要です。

そして、合理的なサイズの文字列の場合、部分文字列、正規表現などを使用してこれを行う方法は複数ありますが、最も効率的な方法は何とかしています。

アップデート:私は何を探していますが、このです:

テキストファイルがあると仮定すると、サイズが20メガバイトの、聖書を言うと、私は回数に単語「イエス」を見つけたい、再びすることができます文字列またはStringBuilderに20 MB全体をロードし、部分文字列または正規表現を使用して一致数を検索する以外に、テキスト内に文字列全体が格納される他のデータ構造があります。実際の検索は複数の方法で行うことができます。私が探しているのは、一時的なストレージのための最も効率的な "データ構造"です。

+2

「巨大テキスト内の単語の出現数をただ一度見つける」および「巨大テキスト内の単語の出現数を複数回見つける」という答えは同じではありません。「一度」の部分のヒント:本には多くの行のテキストがあります。 –

答えて

2

あなたは完全な単語マッチを行うと仮定します(プレフィックスマッチのために働くこともできます)。

カウント情報を持つ聖書からトライを構成します。

単語を照会する必要がある場合は、トライを歩き、カウントを取得します。

部分文字列一致を行う必要がある場合は、接尾辞ツリー(基本的にはトライですが、接尾辞も含めて)を試してみることができます。

これは言葉が変更を照会すると仮定し、聖書が固定されたまま...

0

聖書の大きさは、文字列全体がメモリにキャッシュされないように巨大ではないので、私は前にこの方法を使っていましたが、明らかに雷が速くないでしょう。厳密に言えば、計算の観点から効率的に言えば、これは最速ではありませんが、コーディングのスピードと合理的なスピードから、ナノ秒がカウントされるまでこれが機能すると思います。

 string text = "a set of text to search in. fast to implement."; 
     string key = "to"; 
     MessageBox.Show(text.Split(" ',.".ToCharArray()).Where(a => a == key).Count().ToString()); 

編集:最終バージョンの質問は解決されず、元の質問が誤っている可能性があります。無視する。

+0

これは単なる線形検索にすぎません。少なくとも、HashSetやDictionaryのようなものを使用しようとすると、実際にコードを書くのが遅くなく、はるかに高速に動作します。 –

+0

@Timothy Baldridgeええ、私のコメントで言ったように。私は彼の質問を編集した。 "巨大なテキスト内の単語の出現数を効率的に見つける"。間違いなく、データに対していくつかのクエリを実行するとこれははるかに遅くなりますが、1回のチェックでは、ハッシュテーブルをインクリメントするカウントを読み込むよりもどのように遅いのか分かりませんし、すべての値を繰り返した後に見てくださいハッシュテーブル内で一言で言えば、1回のルックアップはおそらく少し速いですが、私の解決策はいくつかのルックアップやメモリの問題でうまく機能しません。 – deepee1

3

部分文字列は気にしないでくださいが、完全な単語であれば、ハッシュテーブルを使用します。線形時間で構築することができ、サイズは異なる単語の数に比例する。特にDictionary<string,int>。私のマシンでは、聖書全体をハッシュテーブルにロードし、単語「神」のすべてのエントリを見つけるのに約450msかかりました。

+0

あなたはうまくいった、セントトーマス。 – harpo

関連する問題