2012-05-12 34 views
-2

大きなテキストファイル(1Gをかなり上回るサイズ)があり、Javaを使用してそのファイル内の特定の単語の出現を数えたいと思います。ファイル内のテキストは1行に書き込まれるため、1行ずつチェックすることはできません。この問題に取り組む最も良い方法は何でしょうか?Javaを使用してテキストファイルの単語の頻度を数えるには?

+0

あなたはそれに直面している問題は何ですか? –

+0

私はBufferedReaderを使用して行ごとに内容を読み込もうとしましたが、実際には新しい行の文字がないことに気付いた後で、代わりに使う必要があります。私はファイルのサイズがJavaプログラムにとって大きな負担にならないことを望みます。 –

+0

最後に改行文字がないテキストファイルが約1GBのテキストファイルですか?もしそうであれば、 'readLine'はそれに対して動作しません。チャンクを読み込む必要があります。 –

答えて

2

Scanner Javaクラスを使用して、その巨大なファイルを単語単位で消費したいとします。 useDelimiter(...)メソッドを一度呼び出して、単語を分割する方法(空白文字のみ)を構成し、後でhasNext()およびgetNext()を使用してファイルコンテンツをループします。

カウント自体については、簡単にするためにHashMapを使用できます。

+0

+1 ...私のやり方とまったく同じです! –

+0

実際、私はただ一つの単語を数える必要があります。これは統計に関するものではありません。 –

+2

@God_of_Thunder誰もあなたに餌を与えることはありません! –

-2

外部ツールを使用してテキストインデックスを作成できます。その後、この索引で数え切れないほど多くの単語をすばやく見つけることができます。 など。あなたはそのような指数を構築するためにLuceneを得ることができます。そしてsimpeはそれの中の用語の頻度を得る。同様の質問counting the word frequency in lucene indexと記事やコード例へのリンクがあります。

+1

この問題には、はるかに単純で非外的な解決策があります。 –

0

アルファベット順に並べ替える必要があります。データを読み込んだ後にスペースで単語を分割した後、これを行う方法はいくつかあります。並べ替えの前に、特殊文字や句読点も削除する必要があります。

並べ替えが完了すると、ターゲットとする単語がすべて並べて表示されるため、検索結果がO(N)になります。その時点で、ルーピングコンストラクトを使用して、単語の最初のインスタンスが見つかるまで各単語を比較して比較することができます。その時点で、次の単語に到達するまで、各単語を数えるループを続けます。

その時点でコレクション内にその単語のインスタンスがなくなり、検索を停止することができます。

この特定の検索アルゴリズムは、O(N)最悪の場合のシナリオです。あなたの言葉が「りんご」の場合、あなたの言葉が「ゼブラ」よりもはるかに速く完了するでしょう。

正確なニーズに応じて、選択できるアルゴリズムは他にもあります。

私はあなたの質問でこれがプログラミング演習であり、実際の問題ではないと仮定しています。作業に問題がある場合は、この問題はすでに無限に解決されており、Java標準ライブラリのツールを含め、この問題の解決に役立つ多くの検索ライブラリがJava用に用意されています。

+0

実際には私の仕事で問題になっています。プログラム実行中のメモリ消費量が大きすぎるかどうかは疑問なので、実現可能な解決策がほしいだけです。このプログラムは、他のプログラムの結果を正当化するツールに過ぎないため、サーバーではなく通常のデスクトップコンピュータで実行されます。 –

+0

これは、コンピュータが少し遅くなる可能性がありますが、十分なリソースがあり、JVMに十分なリソースが割り当てられている限り、正常であるはずです。それでも、このアルゴリズムはC++のほうがはるかに高速ですが、各単語をポインタに割り当てることができると思います。実際のStringsよりもStringへのポインタをソートする方がはるかに高速です。 – jmort253

+0

C++でうまくいくかもしれませんが、効率はあまり問題にはなりません。私がこのプログラムから必要とするのは、そのファイルのレイアウトが私が望むものかどうかを確認することだけです。だから、それは数回だけ実行され、私はそれをもう使用しません。 –

1

Trieデータ構造のわずかなバリエーションを使用できます。このDSは単語の辞書を作成するために使用されます。あなたが 'Stack'を検索したい場合、 'Sta'を渡すことでtrieを検索することができ、 'Sta'で始まるすべての単語を返します。

あなたの問題では、単語単位でファイルワードをトラバースしてトライに入れることができます。すべての単語にフィールド 'count'を追加します。変更されたtryに挿入すると、 'count'を増やすことができます。今あなたはトライのすべての言葉を数えます。

1Gファイルのほとんどの単語が繰り返されるため、メモリの使用量はあまり多くありません。ファイルを1回だけトラバースする必要があります。また、いったんこのトライを取得すると、パフォーマンスペナルティなしで複数の単語を検索することができます。

EDIT:

あなたは完全一致が必要な場合、私は、HashMapのも良い解決策であることを@Bananeweizenに同意する必要があります。だから一言一語読んでHashMapに入れてください。メモリ使用量はtryと同じにする必要があります。

関連する問題