字符串循环滚动算法

我想出了一个循环滚动自己的术语,希望它能做到

不与现有术语重叠.基本上我正试图想出一个

算法在打印文本中查找循环.

一些例子从简单到复杂

例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.

然后递归地确定包含任何嵌套序列的所有序列的算法表示的长度,从最小的序列开始.评估每个序列时,计算整个文本的最佳算法表示.处理序列或整个文本的算法使用动态编程:分配具有列数的矩阵,等于文本/序列长度和行数,等于算法表示的长度;对区间树进行有序遍历,用所有序列更新该矩阵,每个文本位置都可以;当某个单元格的值不止一个时,可以选择其中任何一个,也可以优先考虑更长或更短的子序列.

点赞