【问题标题】:Datastructure for matching names in text文本中匹配名称的数据结构
【发布时间】:2012-10-05 22:54:03
【问题描述】:

我想查找在文本文件中引用的名称。作者可以有任意数量的姓名和头衔。仅当所有名称都匹配时才找到匹配项(例如,名为“John Doe”的人在仅包含“John”的文本中不匹配

我现在解决的方法是将名称拆分为标记并将第一个标记存储在 HashSet 中,以小写字符串作为键。每个令牌都包含一组名称中的下一个令牌,依此类推。

这会导致大量增加开销的 HashSet 对象。我认为有更好的方法来处理这个问题?如果可能的话,我更喜欢图书馆,但任何事情都会有所帮助

如果那里有好的解决方案,我愿意切换到 Python。

【问题讨论】:

  • 你有一个小的示例文本文件给我们看看吗?
  • 不是我现在的位置。但想想亚马逊。我实际上将使用类似的来源作为查找值(作者)。要匹配的数据材料是书评等,其中包含很多我不感兴趣的文本。
  • 澄清一下,您的意思是您想要一个数据结构来有效地存储 John Smith 先生、John Doe 先生、John Smith 博士、John Doe 博士等吗?
  • @DNA:是的。这将是内存中的数据结构。我将从文件中读取大量文本并对其进行匹配。目前我在 HashSets 中有一个邪恶的 HashSets 组合,但一定有人做得更好

标签: java python string-matching information-retrieval


【解决方案1】:

你可以只使用正则表达式吗?根据文本文件,您可能需要使用多行匹配,如下所示。

    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 等命令行实用程序执行此操作 - 请参阅此related question

更新:为了解决存储名称的问题,用于存储相关字符串的内存高效结构是 Trie,它可能有用 - 虽然可能有很多免费实现据我所知,Java 标准库中没有一个。有关一些建议,另请参阅 this questionthis one

【讨论】:

  • 问题似乎是关于存储,而不是解析。
  • 名字有上千个,所以正则表达式不好用。
【解决方案2】:

据我了解您的问题,您必须存储每个作者的任意姓名列表,并有效地匹配它们。

我假设您已经解决了解析名称、删除“Dr”等非必要/可选部分以及保留“von”和“de”等粒子的问题。您的规范化名称必须是固定大小写的字符串序列(小写可以,但我会坚持使用大写或标题大小写)。

现在,List<String>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”和“J. R. 用户'是同一个人。这应该在不同的层面上解决。

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

您可能还对图书馆规范作者姓名的方式感兴趣。人们使用elaborate schemes 来匹配姓名。

【讨论】:

  • 我有一组要与文本匹配的名称。假设其中一个文本是维基百科文章:en.wikipedia.org/wiki/Spiderman。解析那篇文章,我找到了“Peter Parker”和“Stan Lee”的匹配项。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-01-06
  • 1970-01-01
  • 2021-11-10
  • 1970-01-01
  • 1970-01-01
  • 2015-07-05
  • 1970-01-01
相关资源
最近更新 更多