Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 简单压缩方案的最佳运行时间_Algorithm_Big O_Lossless Compression - Fatal编程技术网

Algorithm 简单压缩方案的最佳运行时间

Algorithm 简单压缩方案的最佳运行时间,algorithm,big-o,lossless-compression,Algorithm,Big O,Lossless Compression,这是一个简单的谜题,在生物信息学中有一些应用。这是一个朋友工作中出现的东西的抽象版本 考虑一个非常简单的压缩方案,其输出由两个操作流组成: put(a):输出字符a dup():复制到目前为止写入的所有输出 为便于注释,请为put('x')编写字符x本身,为dup()编写字符* 例如,“a**b*c”扩展为“aaaaaabc” 要压缩给定字符串s,请找到这两个操作中最短的列表以生成它 例如,对于“aaaaaaaa b”缩短为a**a*b。(a***aab也可以,但长一个字符。) 我的问题是:

这是一个简单的谜题,在生物信息学中有一些应用。这是一个朋友工作中出现的东西的抽象版本

考虑一个非常简单的压缩方案,其输出由两个操作流组成:

  • put(a)
    :输出字符
    a
  • dup()
    :复制到目前为止写入的所有输出
为便于注释,请为
put('x')
编写字符
x
本身,为
dup()
编写字符
*

例如,
“a**b*c”
扩展为
“aaaaaabc”

要压缩给定字符串
s
,请找到这两个操作中最短的列表以生成它

例如,对于
“aaaaaaaa b”
缩短为
a**a*b
。(
a***aab
也可以,但长一个字符。)

我的问题是:实现最佳压缩的最佳运行时是什么?(实现该运行时的算法是什么。)


我相信线性运行时是可能的,但我还没有发现比二次运行时更好的方法。(不要太担心使用额外的空间。)

是的,此压缩方案可以使用线性运行时间

创建一个列表
dp
。此列表的第i个元素将是字符串的第一个
i
元素的最佳压缩

dp[1] = 1
dp[i] = dp[i-1] + 1
if i is even and first i/2 elements of string are equal to second i/2 elements:
    dp[i] = min(dp[i], dp[i/2] + 1)
要检查第一个
i/2
元素是否等于第二个
i/2
元素,可以在字符串和从索引
i/2
开始的后缀之间找到最长的公共前缀。如果此前缀的长度大于或等于
i/2
,则第一个
i/2
元素实际上等于第二个
i/2
元素

使用改进的LCP阵列可以加速此操作

首先,为
O(n)
中的字符串构建一个

然后,为
O(n)
中的后缀数组构建一个

现在,在后缀数组中找到完整字符串的索引。假设它是
i
。现在,从
i
迭代到LCP数组的末尾,用迄今为止看到的最小值替换每个值。类似地,在LCP数组中从
i-1
向下迭代到
0
,用迄今为止看到的最小值替换每个值

完成此操作后,LCP数组中的每个值表示该后缀的最长公共前缀和完整字符串,这是算法所需的。
请注意,这些值是根据已排序的后缀排序的,而不是根据后缀在字符串中的位置排序的。不过,使用后缀数组映射它相当简单。

如何?如果您有想法,请添加答案。谢谢。明天我会详细讨论这个问题。根据我的文献研究,我已经期望LCP和后缀数组可能有用。我还为一个简单的算法绘制了一个草图,其中包含两个滚动哈希:基本上,从[0:I]滚动一个,从[I:2*I]滚动另一个。拉宾指纹可能有用。@Matthias是的,指纹识别听起来像是一个简单得多的想法,在实际场景中可能已经足够好了。哦,我认为在实践中,大多数情况下,天真的方法会工作得很快(比最坏情况下的二次行为快得多)。顺便说一句,我认为你可以在你的解决方案中放弃动态规划,使用贪婪,如果你在你的字符串中向后走的话。为了让指纹识别在理论上起作用,我必须很好地处理错误概率。(到目前为止,我只通过指纹识别实现了O(n log n)运行时。)PS请也看看。顺便说一句,开始时的动态编程位是多余的。后面的贪婪很好用。我也发现了一个新的更简单的线性方案。我很快就要发帖了。