【问题标题】:Search array for a similar / most similar string Java在数组中搜索相似/最相似的字符串 Java
【发布时间】:2018-09-18 11:33:58
【问题描述】:

我正在做一个项目,我在 XML 文件中有书名。然后将这些解析并转换为book 对象的数组列表。现在我想搜索它们。我已经成功实现了Collections.binarySearch()。现在的问题是,由于搜索会寻找完全匹配的内容,因此只有在拼写正确的情况下才会打开一本书。例如,如果我要输入“Harry Pottr”,因为拼写错误,我什么也得不到。我需要知道几件事:

  1. 我将如何制作一个系统,该系统可以为与数组中的某些内容足够接近的输入提供结果。例如:

    ArrayList<Book> library = new ArrayList<Book>();
    为了简单起见,假设我在数组中添加了一些书籍:"Harry Potter", "The Lord of The Rings", "Wonder"

    现在,如果我要在数组中搜索 "Wnder",我希望这本书仍然出现。

  2. 我可以使用Collections.binarySearch() 函数来解决这个问题,还是我需要自己进行二分搜索才能使用它。

最后我想说我是用 Java 做的,所以我只能使用标准库和实际语言。我也知道那里有类似的问题,但没有一个真正回答如何将其应用于搜索的问题。

附:我知道 Levenshtein 距离。但是,如果我想出这一点,我是否可以将其用于已经使用的 Collections 搜索功能。

【问题讨论】:

  • 阅读“Levenshtein 距离”。 Google 会在搜索时使用它,这就是为什么 Harry Pottr 会显示 Harry Potter 的结果。
  • @TimBiegeleisen 是的,我对此进行了一些研究。但是我可以将 Levenshtein 距离应用于 Collections.binarySearch()。
  • 我最近询问了一个类似的question,它可能对您产生关于如何实施不寻找精确匹配的Comparator 的想法时有用。但请注意答案:虽然我的 Comparator 适用于我的用例,但它违反了 Comparator 的约定,这反过来可能导致其他用例中出现不可预测的行为。
  • @JanusVarmarken 感谢您链接问题。您得到的答案之一正是我所需要的。

标签: java string arraylist binary-search similarity


【解决方案1】:

标准库只能带您到此为止。

如果字符串列表(书名)是“小”,那么您可以使用https://github.com/xdrop/fuzzywuzzy(参见FuzzySearch.extractTop)。

否则,如果这太慢了,那么您需要一个基于索引的算法,就像在 https://lucene.apache.org/core/ 中实现的那样。

此外,您不能将二进制搜索应用于模糊匹配,因为没有明确的方法可以对要搜索的字符串列表进行排序以使二进制搜索起作用。

【讨论】:

  • 感谢您的想法,我将尝试研究这些。
【解决方案2】:

Levenshtein 距离是查找两个单词之间相似度的最佳方法之一,但这对二分搜索没有帮助,因为二分搜索适用于已排序的集合,并且可以有效地搜索等于给定的值。

使用 Levenshtein 距离,您不是在寻找与您的搜索词相同的东西,而是在寻找最相似的项目(最小的 Levenshtein 距离)。 您必须评估列表中的每个项目以找出最接近的项目。

另一种可能性是 Soundex。 Soundex 算法试图捕捉单词的发音。它去掉所有的元音,然后对辅音进行编码,给你一个代表单词发音的数字。使用它,您可以存储对象列表及其 soundex 值,然后搜索与您的搜索词接近的 soundex 值。但是,您仍然会遇到无法搜索确切值的问题。

【讨论】:

  • 有趣。所以你的意思是,如果我还想找到相似性,我不应该使用 binarySearch?
  • 是的,二分搜索旨在找到完全匹配的内容,而不是查看每个元素,而是关注效率。本质上是对所考虑的每个项目的是/否决定。您正在寻找最接近的匹配项,除非我遗漏了什么,否则它不适用于二分搜索算法,因为您无法对项目进行排序,并且您可能需要检查每个项目。
  • 顺便说一句,这里有一篇文章可能对您有所帮助:stevehanov.ca/blog/index.php?id=114 它描述了使用 Trie 结构,以及一堆其他优化来在非常大的单词列表中搜索最佳 Levenshtein 匹配迅速地。示例代码使用 Python 编写,但希望您可以使用所提供的想法。
  • 感谢您的链接。也感谢上面的解释,我现在明白为什么 binarySearch 有你所说的限制。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-06
  • 2014-01-25
  • 1970-01-01
相关资源
最近更新 更多