我想出了一个循环滚动自己的术语,希望它能做到
不与现有术语重叠.基本上我正试图想出一个
算法在打印文本中查找循环.
一些例子从简单到复杂
例1
鉴于:
a a a a a b c d
我想说:
5x(a) b c d
或算法:
for 1 .. 5
print a
end
print b
print c
print d
例题
鉴于:
a b a b a b a b c d
我想说:
4x(a b) c d
或算法:
for 1 .. 4
print a
print b
end
print c
print d
示例3
鉴于:
a b c d b c d b c d b c e
我想说:
a 3x(b c d) b c e
或算法:
print a
for 1 .. 3
print b
print c
print d
end
print b
print c
print d
它并没有让我想起我所知道的任何算法.我觉得有些像
问题可能含糊不清,但找到解决方案之一就足够了
现在.效率总是受欢迎但不是强制性的.我怎样才能做到这一点?
编辑
首先,感谢所有的讨论.我已经改编了LZW算法
从rosetta开始,我就把它跑了
输入:
abcdbcdbcdbcdef
这给了我:
a
b
c
d
8 => bc
10 => db
9 => cd
11 => bcd
e
f
我有一本字典:
a a
c c
b b
e e
d d
f f
8 bc
9 cd
10 db
11 bcd
12 dbc
13 cdb
14 bcde
15 ef
7 ab
它看起来很适合压缩,但它并不是我想要的.我需要的
在我的例子的算法表示中更像是压缩
哪个会:
>后续序列(如果序列重复,则不会有其他序列
之间的顺序)
>没有字典,只有循环
> irreducable
>具有最大序列大小(这将最小化算法
表示)
>并且假设允许嵌套循环(与我之前所说的相反)
评论)
最佳答案 我从一个算法开始,它给出了最大的序列大小.虽然它并不总是最小化算法表示,但它可以用作近似算法.或者它可以扩展到最优算法.
>从LCP array开始为您的文本构建Suffix array.
>对LCP数组的索引数组进行排序,首先是LCP数组中较大元素的索引.这将重复相同长度的序列组合在一起,并允许从最大序列大小开始以贪婪的方式处理序列.
>提取后缀数组条目,按LCP值分组(按组I表示具有选定LCP值的所有条目以及具有较大LCP值的所有条目),并按文本中的位置对它们进行排序.
>过滤出位置差异不等于LCP的条目.对于剩余的条目,获取长度的前缀,等于LCP.这给出了文本中所有可能的序列.
>将按起始位置排序的序列添加到有序集合(例如,二叉搜索树).在排序的LCP中按顺序添加序列,因此首先添加更长的序列.仅当序列是独立的或者其中一个完全嵌套在另一个中时才添加序列.相交间隔将被忽略.例如,在caba caba bab序列ab与caba相交,因此它被忽略.但是在cababa cababa babab中,ab的一个实例被丢弃,2个实例完全在更大的序列内,2个实例完全在它之外.
>最后,此有序集合包含生成算法表示所需的所有信息.
例:
Text ababcabab
Suffix array ab abab ababcabab abcabab b bab babcabab bcabab cabab
LCP array 2 4 2 0 1 3 1 0
Sorted LCP 4 3 2 2 1 1 0 0
Positional difference 5 5 2 2 2 2 - -
Filtered LCP - - 2 2 - - - -
Filtered prefixes (ab ab) (ab ab)
算法草图,产生最小算法表示.
从先前算法的前4个步骤开始.第五步应该修改.现在无法忽略交叉间隔,因此每个序列都会添加到集合中.由于集合现在包含交叉间隔,因此最好将其实现为某些高级数据结构,例如Interval tree.
然后递归地确定包含任何嵌套序列的所有序列的算法表示的长度,从最小的序列开始.评估每个序列时,计算整个文本的最佳算法表示.处理序列或整个文本的算法使用动态编程:分配具有列数的矩阵,等于文本/序列长度和行数,等于算法表示的长度;对区间树进行有序遍历,用所有序列更新该矩阵,每个文本位置都可以;当某个单元格的值不止一个时,可以选择其中任何一个,也可以优先考虑更长或更短的子序列.