Java 高效的字符串索引,用于全文索引

Java 高效的字符串索引,用于全文索引,java,string,algorithm,data-structures,indexing,Java,String,Algorithm,Data Structures,Indexing,我正在寻找一个数据结构来解决以下问题。接收一个相当短的字符串(比如5000万,少于30个字符)的大集合作为输入,并根据需要对它们进行索引。然后,回答以下问题:我给出一个新字符串,您提供的字符串来自初始集,与提供的字符串类似(比如,10个最好的字符串)。“相似性”的概念在理想情况下类似于编辑距离或Jaro-Winkler距离,或其近似值,但它应能适应拼写和词序的细微变化,以及添加垃圾词。(例如,与标准索引任务不同,如果“foo-bar”确实是集合中最接近的字符串,则请求它应生成“foo”) 举个例

我正在寻找一个数据结构来解决以下问题。接收一个相当短的字符串(比如5000万,少于30个字符)的大集合作为输入,并根据需要对它们进行索引。然后,回答以下问题:我给出一个新字符串,您提供的字符串来自初始集,与提供的字符串类似(比如,10个最好的字符串)。“相似性”的概念在理想情况下类似于编辑距离或Jaro-Winkler距离,或其近似值,但它应能适应拼写和词序的细微变化,以及添加垃圾词。(例如,与标准索引任务不同,如果“foo-bar”确实是集合中最接近的字符串,则请求它应生成“foo”)

举个例子,假设字符串集合是{“Charles Dickens”、“Mary Shelley”、“Robert Stephenson”}。查询“狄更斯,查尔斯”应找到“查尔斯·狄更斯”。查询“by Shelley”应返回“Mary Shelley”


对于大型集合来说,逐个计算查询字符串与集合中所有字符串的相似性的简单方法速度太慢。什么样的数据结构才能更有效地回答此类查询?理想情况下,我会寻找一个很好的Java实现。我想到两个建议:

1) 选择一个满足三角形不等式的距离函数,并使用-可能会提供一些加速,但可能不会达到数量级


2) 猜测最接近的匹配将包括至少一段k个连续字符,这是两个字符串之间的精确匹配。构建一个数据结构,例如,通过哈希表查找,可以找到集合中至少有k个与查询字符串的某个部分相同的连续字符的所有字符串,然后使用距离函数查看由此返回的字符串中哪一个是最佳匹配的。应该是快速的,但有时会错过正确的答案。

作为琐碎方法的替代方法,您可以通过两个步骤解决问题:

  • 建立一个所有字符串中出现的单词索引,它允许您查找包含给定单词的句子。这应该远远少于5000万(如果我们说的是自然语言的话)。你可能不在乎“foop bar”->“foo”,因为你只有单词
  • 将查询拆分为单词。对于每个单词,找出包含该单词的所有句子。对于每个句子,使用度量计算与查询字符串的相似性

  • 另一个好处是,在许多情况下,您可以在不重建单词索引的情况下更改度量。

    您正在查找的内容与拼写检查器建议可能的更正时所做的非常相似。你可能想看看他们到底是怎么做的。我认为Lucene不行,因为“foo-bar”甚至“foop-bar”这样的查询都会返回“foo”。我不想只在单词级别进行比较,也不想要求所有查询词都存在。此外,我希望能够适应任意编辑,我不确定Lucene是否能够做到这一点。第一个近似值是“KWIC索引”。Lucene肯定能够(几乎)完成任何你认为可行的事情。您的示例属于Lucene功能的小范围。请记住,Lucene是一个API,特定于您需求的功能的实现就在您的手中。Lucene正是完成这项艰巨工作的工具。我非常关心“foop bar”->“foo”,因为可能会出现拼写错误和拼写变化,或者说,“foo_bar”与“foo bar”的对比。拆分成文字是一个好主意,比单纯的方法要好,但不够健壮。