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”等粒子的问题。您的规范化名称必须是固定大小写的字符串序列(小写可以,但我会坚持使用大写或标题大小写)。

现在, a List<String>orString[]将作为HashMap包含其他详细信息的 a 的键。恐怕这不会很好,因为两者都是可变的,而且我不确定他们的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”是同一个人。这应该在不同的层面上解决。

如果您更详细地说明您的情况,并举一两个例子,答案可能会更好。

您可能还对图书馆规范作者姓名的方式感兴趣。人们使用精心设计的 方案来匹配名称。

于 2012-10-15T22:19:35.227 回答