0

テキスト ファイルで参照されている名前を検索したい。著者は、任意の数の名前とタイトルを持つことができます。すべての名前が一致する場合にのみ一致が検出されます (たとえば、「John Doe」という人物は、「John」のみを含むテキストでは一致しません)。

私が今解決した方法は、名前をトークンに分割し、最初のトークンを小文字の文字列をキーとして HashSet に格納することです。各トークンには、名前などの次のトークンのセットが含まれます。

これにより、オーバーヘッドを追加する多くの HashSet オブジェクトが発生します。これを処理するより良い方法があると思いますか?できれば図書館がいいのですが、なんでもいいです。

そこに良い解決策があれば、私はPythonに切り替えることにオープンです。

4

2 に答える 2

0

正規表現しか使えませんか?テキスト ファイルによっては、次に示すように複数行の一致を使用する必要がある場合があります。

    Pattern p = Pattern.compile("John\\s+Doe", Pattern.MULTILINE);
    Matcher m = p.matcher("I am looking for John \nDoe, I am.");        
    System.out.println(m.find());

これは、次のようなコマンドライン ユーティリティでも実行できます。pcregrepこの関連する質問を参照してください。

更新:名前を保存する問題に対処するために、関連する文字列を保存するためのメモリ効率の良い構造はTrieです。これは役に立つかもしれません。Java 標準ライブラリにはありませんが、おそらく多くの無料の実装があります。私の知る限り。いくつかの提案については、この質問とこれも参照してください。

于 2012-10-15T21:58:27.687 に答える
0

私があなたの問題を理解している限り、著者ごとに名前の任意のリストを保存し、それらを効率的に照合する必要があります。

名前を解析し、「Dr」などの必須ではない/オプションの部分を削除し、「von」や「de」などの粒子を保持するという問題を解決したと思います。正規化された名前は、固定された大文字の文字列のシーケンスでなければなりません (小文字でも構いませんが、大文字またはタイトル ケースを使用します)。

ここで、List<String>orは、他の詳細を含むString[]へのキーとして機能します。HashMapどちらも可変であるため、残念ながらこれはうまく機能しませんhashCode()

だから私はこのようなものを思いつきます:

class AuthorName(object) {
  private String[] parts;
  public AuthorName(String... name_parts) {
    assert name_parts.length > 0;
    parts = name_parts;
  }

  @Override
  public int hashCode() {
    // hashCode() that only depends on name parts
    int result = 0;
    for (int i=0; i < parts.length; i+=1) result ^= part.hashCode();
    return result;
  }
}

Map<AuthorName, ...> authors = new HashMap<AuthorName, ...>();
authors.put(new AuthorName('John', 'Doe'), ...);
assert authors.get(new AuthorName('John', 'Doe')) != 0

これは、'Joe Random User'、'Joe R User'、および 'JR User' が同一人物であるなど、考えられる多くの問題に対処していません。これは、別のレベルで対処する必要があります。

例を 1 つまたは 2 つ挙げて、より詳細にケースを説明すると、より良い回答が得られる可能性があります。

ライブラリが著者名を正規化する方法にも興味があるかもしれません。人々は名前を一致させるために精巧な スキームを使用します。

于 2012-10-15T22:19:35.227 に答える