2011-01-10 16 views
1

iPhoneアプリのNSStringに共通のファーストネームが含まれているかどうかを確認するのが最善の方法です。私は、新しい行で区切られた〜5500の一般的なアメリカのファーストネームのソートされたフラットテキストファイルを持っています。私が名前の中で探しているNSStringは、それほど長くはありません。通常は、通常の文のサイズです。NSStringにiPhoneの一般的なファーストネームが含まれていないか確認してください。

ソートされたリストをメモリにロードしてから、NSString内のすべての単語を繰り返してリストのバイナリ検索を実行して、その単語が共通名であるかどうかを判断しました。

CoreDataまたはSQLiteテーブルにこの名前リストを入れてクエリを実行する方が良いでしょうか?私が理解していることは、もし私がそのルートを訪れれば、リスト全体をメモリにロードする必要はないということです。

私はこの状況が単語ゲームの単語辞書によくある問題だと推測しています。そのため、高速検索のベストプラクティスが何であるか不思議です。ありがとう!

+0

「NSString内に共通のファーストネームが含まれているかどうかをチェックする」という意味を明確にすることはできますか。これは、「Johnというユーザーが入力しました」という意味ですか、「John」を意味していますか?つまり、チェックしている文字列は名前だけで構成されているのでしょうか、名前の他に「その他のもの」が含まれている文字列内に名前を入れなければなりませんか?これにより、選択されたアプローチに差異が生じる可能性があります。また、「迅速に」これを行う必要がありますか? – johne

+0

名前は、名前の他に「その他のもの」を含む文字列内になければなりません。文字列が長くない、50〜100文字の標準文章。できるだけ早くそれを望みますが、記憶とのトレードオフがあることを理解しています。 –

+0

スピードが問題であれば、おそらく〜5500の名前のDFAをその場で構築していました。必要に応じて、DFAを不揮発性ストレージにシリアル化することができます。 DFAはUnicode対応でなければならず、おそらく便宜のためにUTF8を使用します。次に、 'CFStringGetCStringPtr' /' CFStringGetBytes'を使用して、文字列のUTF8コピーを取得し、その上でDFAを実行します。パフォーマンスは〜O(n) 'となります。ここで' n'は検索する文字列のサイズです。 – johne

答えて

2

SQLiteはルックアップの速度とメモリ使用量を最小限に抑えるという点で理想的です。また、必要に応じてインターネット経由でファーストネームリストを更新することも可能です。

特に、ORMのような機能を必要としないため、コアデータを使用すると(実際にはSQLiteを包括するラッパー)、このインスタンスでは過剰使用になります。

2

NSSetも同様に便利です。 Dave DeLong's answerは、NSSetsが一定のルックアップ時間、すなわちO(1)を有することを示している。

名前をNSMutableSetに1つずつ読み込みます。これは最も遅い部分ですが、一度だけ行う必要があります。ファイルが単純な行区切りのファイルであれば、行単位の入力はCocoaでうまくサポートされていないため、ファイルの読み込みに標準のCライブラリを使用する方が簡単かもしれません。

その後、[nameSet containsObject:name]を使用して、リストに含まれているかどうかを確認します。

このアプローチの欠点のカップル:

  1. テストしたい名前がセットに名前と同じ場合でなければなりません、それは“ポール”と“ポール”で異なる文字列です。これを回避するには、すべての名前をセットに挿入する前に小文字に変換し、チェックしたい名前を小文字に変換してからセットと照合します。
  2. すでに受け入れられている回答に進むだけで簡単かもしれません。
+0

このアプローチはもっと簡単ですが、私はSQLiteを使うつもりだと思うので、すべてを先にメモリにロードする必要はありません。実際には5500エントリしか問題にならないかもしれません。 –

+0

@ Joe:はい、なぜ、1列のテーブルで何かを探しているだけで、SQLパーサのオーバーヘッドを楽しむことができるときに、迅速な検索に特化したフレームワーク提供のデータ構造を使用しています。 – dreamlax

関連する問題