【问题标题】:Find longest common substring of multiple strings using factor oracle enhanced with LRS array使用 LRS 数组增强的因子 oracle 查找多个字符串的最长公共子字符串
【发布时间】:2012-08-10 23:58:08
【问题描述】:

我们可以使用带有后缀链接 (paper here) 的因子-oracle 来计算多个字符串的最长公共子字符串吗?这里,substring 表示原始字符串的任何部分。例如“abc”是“ffabcgg”的子字符串,而“abg”不是。

我找到了一种方法来计算两个字符串s1s2 的最大长度公共子字符串。它通过使用不在其中的字符连接两个字符串来工作,例如'$'。然后对于长度为i >= |s1| + 2的串联字符串s的每个前缀,我们计算其LRS(最长重复后缀)长度lrs[i]sp[i](其LRS第一次出现的结束位置)。最后,答案是

max{lrs[i]| i >= |s1| + 2 and sp[i] <= |s1|}

我写了一个使用这种方法的C++程序,在我的笔记本电脑上|s1|+|s2| &lt;= 200000,使用oracle因子,可以在200ms内解决问题。

s1 = 'ffabcgg'
s2 = 'gfbcge'
s = s1+'$'+s2 
  = 'ffabcgg$gfbcge'
p: 0 1 2 3 4 5 6 7 8 9 10 11 12 13
s:  f f a b c g g $ g f  b  c  g  e
sp: 0 1 0 0 0 0 6 0 6 1  4  5  6  0
lrs:0 1 0 0 0 0 1 0 1 1  1  2  3  0

ans = lrs[13] = 3

我知道使用后缀数组和后缀树可以高效地解决这两个问题,但是我想知道是否有使用因子oracle的方法来解决它。我对这个很感兴趣,因为因子oracle很容易构造(30行C++,suffix-array大约需要60行,suffix-tree需要150行),而且运行速度比suffix-array和suffix-tree快。

你可以在this OnlineJudge测试你的第一个问题的方法,在here测试第二个问题。

【问题讨论】:

  • @jogojapan 感谢您的耐心等待!我应该为我糟糕的英语道歉。
  • 完全没有(而且我也不是母语人士)。无论如何,我认为对 SO 上的因子预言有疑问真是太好了!
  • @Ray:你/你能在任何地方分享你对因子预言机构建的实现吗?我对这个话题很感兴趣,而且我通常比正式论文更擅长阅读源代码:)
  • @500-InternalServerError 您可以在gist.github.com/ZhanruiLiang/d50bf9f17b58916c8bc7 找到代码。但是,代码很脏(编程竞赛风格),概念也​​很棘手,您应该阅读论文才能理解它。
  • 你关心因子oracle,还是只想解决常见的子字符串问题?因为如果你只关心常见的子串问题,已经有一个线性时间算法:en.wikipedia.org/wiki/Longest_common_substring_problem

标签: algorithm automata suffix-tree suffix-array


【解决方案1】:

我们可以使用带有后缀链接的因子-oracle(此处为论文)来计算 多个字符串的最长公共子串?

我不认为该算法非常适合(它旨在分解单个字符串),但您可以通过使用唯一分隔符连接原始字符串来使用它。

给定abcdefghijcdeklmncdop,找出最长的公共子串cd

# combine with unique joiners
>>> s = "abcdefg" + "1" + "hijcdekl" + "2" + "mncdop" 
>>> factor_oracle(s)
"cd"

作为其线性时间和空间算法的一部分,因子预言机快速重新发现输入字符串之间的断点,作为其搜索公共因子的一部分(独特的连接器提供并立即提示停止扩展找到的最佳因子到目前为止)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-27
    • 1970-01-01
    • 1970-01-01
    • 2013-09-13
    相关资源
    最近更新 更多