字符串匹配

时间:2009-01-14 00:40:38

标签: algorithm search matching

让我解释一下这个问题:

  1. 假设我有一个库,该库包含许多书籍,每本书都包含章节,每章都包含字符串(字符串以点“。”开头和结尾)。
  2. 序列,库 - >书 - >章节 - >字符串。
  3. 我从书中提取字符串,让我们称之为“书籍字符串”。
  4. 我有一个系统,用户可以在搜索表单中输入字符串,系统应该从“books strings”返回输入字符串的完全匹配。如果输入的字符串与书籍字符串中的任何字符串都不匹配,则不会返回任何内容。
  5. 我考虑并找到了解决方案,我将MD5所有书籍字符串并保存哈希书籍字符串。当用户输入要搜索的字符串时,我也会对其进行哈希处理并在哈希书籍字符串中搜索匹配项。它更便宜(每个字符串为32或64个字符),比普通搜索更快,它只返回完全匹配。

    有任何意见,想法,更好的解决方案吗?

    P.S。这种算法的名称是什么?搜索或匹配?

9 个答案:

答案 0 :(得分:4)

这不错,但你应该调查Lucene。它是一个公共共享软件文本索引和搜索工具,用多种语言实现,其中一个是.Net ..(你在做什么平台/语言?)我用它来自由文本搜索公共互联网上的网站内容主要模式是在paritcula细分市场提供内容(众多杂志文章,书籍摘录等)Lucene为我们工作得非常好。

Lucene

答案 1 :(得分:4)

有很多用于搜索字符串的算法,从Boyer-Moore算法等简单方法到suffix trees等复杂数据结构。完整的演示文稿可在以下网址找到:

  • Gusfield,Dan(1999),字符串,序列和树的算法。剑桥:大学出版社。

然而,对于您的情况,将书籍文本拆分为单个标记(单词)可能更有意义,并将它们存储在索引中(例如,只需在Map中,或使用完整框架进行索引和搜索,如Lucene)。

答案 2 :(得分:3)

它被称为hashing,可以被认为是搜索或匹配。

您应该通过比较用于生成哈希的字符串来验证您的MD5哈希是否正确,因此您没有任何false positives

另一件需要考虑的事情是支持某种从搜索开始可能是有益的。考虑

Mary Queen of Scots
Mary Livingston
Mary Had a Little Lamb, and other silly stories

以搜索开头为Mary,应该返回这三个记录,甚至更多。 虽然MD5类型的哈希值很快,但应考虑其他答案中提供的技术,以便为您的环境找到最佳的收益/成本平衡。

答案 3 :(得分:2)

您应该将每个图书章节转换为suffix tree。后缀树是一种Trie(由divo提到)。

后缀树专门用于快速文本搜索。后缀树的一个优点是搜索长度为n的字符串是O(n)时间。这与你的算法思想一样好(渐近)(因为散列一个字符串花费O(n)时间),但更灵活,因为它甚至可以用于部分句子。如果您使用句号开始/结束搜索,它会缩减为句子搜索。

澄清:更确切地说,你将拥有一个后缀树。

答案 4 :(得分:1)

您可能希望使用Trie或其他基于树的数据结构来存储字符串数据。

  

也可以用trie替换a   哈希表,它有它   以下优点:

     
      
  • 与不完美的哈希表相比,查找特里结构中的数据在最坏的情况下(O(m)时间)更快。   不完美的哈希表可以有密钥   碰撞。一个关键的碰撞是   不同的哈希函数映射   键到散列中的相同位置   表。最糟糕的查找速度   不完美的哈希表是O(N)时间,   但更典型的是O(1),有   O(m)时间用于评估哈希值。

  •   
  • trie中没有不同键的碰撞。

  •   
  • trie中的桶,类似于哈希表桶   存储密钥冲突只是   如果一个键是必要的   与多个值相关联。
  •   
  • 无需提供哈希函数或更改哈希   函数作为更多键添加到a   线索。
  •   
  • 特里可以提供条目的字母顺序   按键。
  •   
     

尝试也有一些缺点:

     
      
  • 在某些情况下,尝试可能比哈希表更慢以便查找   数据,特别是如果数据是   直接访问硬盘驱动器   或其他一些二级存储设备   随机访问时间很长的地方   与主记忆相比。
  •   
  • 将所有键表示为字符串并不容易,例如浮动   点数,可以有多个   字符串表示相同   浮点数,例如1,1.0,   1.00,+ 1.0等
  •   
  • 尝试通常比哈希表空间效率低。
  •   

(见http://en.wikipedia.org/wiki/Trie

答案 5 :(得分:0)

Trie是最好的方法。这就是所谓的后缀图。使用Trie优于哈希的优点是,使用trie可以非常轻松地显示自动完成类型语法。找到单词的时间是O(n),其中n是单词的长度。在Trie中的每个节点上,您需要存储包含特定单词的书籍列表。

答案 6 :(得分:0)

我同意Trie - 添加一个,使用soundx算法转换trie id / node的字符串 - 所以考虑拼写错误

答案 7 :(得分:-1)

这称为哈希。您的方法可能有效,但不是很灵活。同样,您只会检索完全匹配。两个preimages也可能共享相同的图像(两个不同的字符串哈希到相同的值),但它极不可能,因此这不是一个真正的问题。我建议不要因为缺乏灵活性而反对它,但如果这不打扰你那么我想这对你有用。这与人们用于存储和验证密码的技术基本相同(除此之外,您显然没有使用任何“盐”值)。

答案 8 :(得分:-1)

首先,它听起来像你应该使用的是一个数据库 - 这几乎就是数据库的用途。 (如果您希望将其嵌入到您自己的应用程序中,请查看SQLite,这是一个轻量级DBMS,旨在用作嵌入式库。)

其次,你的哈希解决方案只返回完全匹配并不完全正确...因为MD5摘要是128位,这意味着任何给定的字符串对都有1到2 ^ 128的机会产生相同的哈希值。是的,这是一个很小的数字,但如果你有很多书,你会有一对很多的字符串。因此,一旦比较了哈希值,就需要进行全文比较以消除误报。