【问题标题】:algorithms for fast string approximate matching快速字符串近似匹配算法
【发布时间】:2013-05-03 04:34:59
【问题描述】:

给定一个源字符串sn 相等长度的字符串,我需要找到一个快速算法来返回那些最多具有k 字符的字符串,这些字符与源字符串s 在每个对应处不同位置。

什么是快速算法?

PS:我必须声明这是一个academic 的问题。如果可能的话,我想找到最有效的算法。

我还错过了一条非常重要的信息。 n 等长字符串组成一个字典,许多源字符串s 将被查询。似乎有某种预处理步骤可以提高效率。

【问题讨论】:

  • 查看两个字符串之间的 Levenshtein 距离
  • 我看不出 Levenshtein 在这里有什么意义; OP 需要一个粗略的近似值,而不是对差异的精确度量。
  • s 的大小与n 的大小相同吗?

标签: string algorithm


【解决方案1】:

我的直觉只是遍历每个字符串n,维护一个计数器来计算与s 不同的字符数,但我并不是说这是最有效的解决方案。但是它会是 O(n),所以除非这是一个已知的性能问题或学术问题,否则我会继续这样做。

【讨论】:

    【解决方案2】:

    【讨论】:

      【解决方案3】:

      鉴于字符串是固定长度的,你可以计算两个字符串之间的Hamming distance来确定相似度;这是字符串长度的 O(n)。所以,最坏的情况是你的算法是 O(nm) 来比较你的字符串和 m 个单词。

      作为一种替代方法,一种快速的解决方案也是一种消耗内存的方法,就是将您的字典预处理为地图;键是一个元组 (p, c),其中 p 是字符串中的位置,c 是字符串中该位置的字符,值是在该位置具有字符的字符串(因此“the”将在地图中{(0, 't'), "the"}, {(1, 'h'), "the"}, {(2, 'e'), "the"})。要查询映射,遍历查询字符串的字符并使用检索到的字符串构造结果映射;键是字符串,值是从主映射中检索字符串的次数(因此对于查询字符串“the”,键“thx”的值为 2,键“tee”的值为值为 1)。最后,遍历结果映射并丢弃值小于 K 的字符串。

      当结果映射完成时,您可以通过丢弃不可能等于 K 的键来节省内存。例如,如果 K 是 5 并且 N 是 8,那么当您到达查询字符串的第 4-8 个字符时,您可以丢弃任何不在结果映射中的检索字符串,因为它们不可能有 5匹配的字符。或者,当您完成查询字符串的第 6 个字符后,您可以遍历结果映射并删除值小于 3 的所有键。

      如果需要,您可以将主要的预计算映射卸载到 NoSql 键值数据库或类似的东西,以节省主内存(而且您不必在每次程序时都预计算字典重启)。

      您可以将位置和字符连接成一个字符串,而不是将元组 (p, c) 作为键存储在主映射中(因此 (5, 't') 变为“5t”,并且 (12, 'x') 变为 "12x")。

      【讨论】:

        【解决方案4】:

        在不知道每个输入字符串中匹配字符的位置的情况下,对于特定字符串,您可能需要检查每个字符,无论您检查它们的顺序是什么。因此,只需逐个字符地迭代每个字符串是有意义的-字符并保留不匹配总数的总和。如果i 是到目前为止的不匹配数,则在i == k 时返回false,当字符串中剩余的未检查字符少于k-i 时返回true

        请注意,根据字符串的长度和允许的不匹配数量,迭代整个字符串可能比执行这些检查更快,或者仅在每两个字符之后执行它们。试一试,看看如何获​​得最快的性能。

        【讨论】:

          【解决方案5】:

          如果我们大声思考,我的方法是:P 如果不遍历每个 n 字符串,我看不到这样做的方法,但我很高兴得到纠正。为此,它会从一个预处理开始,以保​​存第二组 n 字符串,以便字符按升序排列。

          然后,比较的第一部分是检查每个 n 字符串,一次检查一个字符,比如 n's 中的每个字符,比如 s'

          如果s' 小于n' 则不相等并移至下一个s'。如果n' 小于s',则转到下一个n'。否则记录一个匹配的字符。重复此操作,直到找到 k 未命中匹配或找到替代匹配并相应地标记 n

          为了进一步考虑,可以对n 中的每个相邻字符串进行额外的预处理,以查看不同字符的总数。这可以在比较字符串ns 时使用,如果这些和相邻的n 之间存在足够的差异,可能不需要比较它?

          【讨论】:

            猜你喜欢
            • 2010-09-08
            • 2017-12-23
            • 2015-11-27
            • 1970-01-01
            • 1970-01-01
            • 2011-05-11
            • 2014-03-15
            • 2012-06-03
            • 2013-07-10
            相关资源
            最近更新 更多