这不是作业;我正在尝试简化和增强用C#/ Winform / Sql Server 2008编写的现有笨重的GUI界面。如果你能够提取某些特定于这些技术的东西,那将会很酷,但如果你能指出我的其他东西,比如Java / MySql解决方案,那么我也会很高兴。
已经提出了类似的问题,但问题/答案并不像我追求的那样先进:Given a list of words - what would be a good algorithm for word completion in java? Tradeoffs: Speed/efficiency/memory footprint
假设我有一个包含书籍信息的表格:标题,作者姓名,描述。我知道,这三个都不一定属于同一个表,但让我们假设这样做是有意义的。因此,当用户在文本框/组合框或某些自定义控件中键入内容(比如“Hari po”)时,他们应该得到的第一个建议可能是“哈利波特”,以及相应的描述和作者。为了简化问题,我们将搜索限制为仅限标题。请注意,我不在乎“Hari”听起来像“Harry” - 该应用程序并非针对非母语人士,但我确实关心“Hari po”这一事实只是远离“Harry Po”的几次击键。因此,http://en.wikipedia.org/wiki/Levenshtein_distance浮现在脑海中,但这并不是我所需要的,因为我希望一旦开始输入就能获得有意义的结果(想想Google建议的目的不同)。我需要某种修改后的Levenshtein距离算法,该算法适用于部分匹配,并且不假设我输入的内容应该是我想要匹配的文本的开头。例如,这本书可能被称为“这个名叫哈利波特的男孩如何影响我们的社会。”,我确实希望这个标题出现在搜索中,但是,我希望看到类似“哈利波特与秩序”的内容。凤凰城“登顶,因为我的查询从此开始。
我可以针对所有可能的查询长度+/- 2的子字符串多次尝试Levenshtein距离,然后以某种方式对字符串中的子字符串“sort off”出现的位置进行加权,然后选择最大值匹配系数。我这样做的第一个问题是效率低下。其次,必须有一种方法可以获得更好的结果,即使速度不是问题。第三,有人之前肯定做过类似的事情,为什么要重新发明轮子?
数据库中唯一行的数量最多为20,000。我所追求的有点像Google搜索建议或Visual Studio 2010 IntelliSense(代码自动完成),除了它不应该试图记住用户过去输入的内容并根据它调整建议。不需要进行查询扩展;只是处理实际内容。从用户角度来看,它应该与Google搜索和IntelliSense类似,例如它应该提出一些排名选择,并提出一种智能的方法来在正确的点上删除该列表(例如,如果没有真正匹配查询,那么建议什么都没有,而不是显示最差的最佳拟合)并且如果前几个结果具有较强的排名,但后续的结果相对于最高结果要弱得多,那么可能隐藏弱结果。
也许您知道一个合理大小的开源工具/库,其中包含暴露且可读的源代码,我可以从中获取想法?
我的下一个问题是如何最好地处理搜索词可以应用于标题和/或作者和/或描述的情况,但我怀疑我当前的问题已经加载。
如果对我所追求的内容不清楚,请提出澄清问题。
答案 0 :(得分:1)
我建议好好看看Lucene。它支持各种查询类型,包括(我认为)增量,近似搜索。此外,它是开源和免费的。 :)
答案 1 :(得分:1)
如果您在Google中输入“hari po”,那么靠近顶部的建议将正确“harry potter” Google使用“该死的酷算法“。您与 Levenhstein编辑距离并不相符:Google正在使用BK-trees IIRC。
据我所知,它基本上是由 Levenhstein编辑距离构建的树。
现在可能有几篇关于这个主题的论文。几年前,我第一次读到它的时候,在一个名为“该死的酷算法”的博客上:
http://blog.notdot.net/2007/4/Damn-Cool-Algorithms-Part-1-BK-Trees
但是你必须知道,尽管 Levenhstein编辑距离是微不足道的(它可以在大约20行代码中实现),但bk-tree看起来像是另一个开发的野兽。 ..
答案 2 :(得分:0)
也许你想寻找一个三元组搜索?三字母搜索需要创建输入的3个字母的每个可能性,并在匹配中查找类似的字符串。 http://en.wikipedia.org/wiki/Trigram
答案 3 :(得分:0)
对于简单的完成算法,您可以将KWIC索引与基数树组合在一起。
基本上,您将获取每个索引字符串,识别“重要”潜在起点,并根据这些潜在起点生成N个旋转的字符串副本。
然后在字符串上构建一个基数树,这样当你输入“Harry”时,你会在“Harry”之后找到所有可能的下一个单词。
虽然这可能听起来确实会爆炸你的数据库的大小,但它实际上只会使它加倍,这取决于你选择“重要”起点的方式。 (除了进行有效的搜索之外,基数树比单独存储每条线更紧凑。)