Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.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_String_Sorting - Fatal编程技术网

Algorithm 如何在不使用矩阵的情况下对字符串旋转排序

Algorithm 如何在不使用矩阵的情况下对字符串旋转排序,algorithm,string,sorting,Algorithm,String,Sorting,我想对字符串的旋转进行排序。 例如: 对于S='abaeb',旋转可以是'baeba' 我需要获得S的索引列表,按字典顺序排序。 在我们的示例中:V=02413 答案必须排除普通矩阵行排序。如果我理解正确,您有一个输入字符串,并且您正在考虑所有旋转。例如,N长度字符串的N次旋转为,例如: rotations("abcd") -> ["abcd"*, "dabc", "cdab", "bcda"] 您希望编写一个比较器函数,compare(rotation1,rotation2),在*原始

我想对字符串的旋转进行排序。
例如:

对于
S='abaeb'
,旋转可以是
'baeba'

我需要获得
S
的索引列表,按字典顺序排序。
在我们的示例中:
V=02413


答案必须排除普通矩阵行排序。

如果我理解正确,您有一个输入字符串,并且您正在考虑所有旋转。例如,N长度字符串的N次旋转为,例如:

rotations("abcd") -> ["abcd"*, "dabc", "cdab", "bcda"]
您希望编写一个比较器函数,
compare(rotation1,rotation2)
,在*原始旋转是
abcd
的上下文中,该函数将说明
rotation1
还是==
rotation2
,或者具有一个函数
键(旋转)
,相当于上述比较器功能

如果这是错误的,请澄清问题。=)如果正确,您的回答如下:

original = 'abcd'

letterPositions = defaultdict(set)
for i,letter in enumerate(original):
    letterPositions[letter].add(i)

def numIndicesRotated(rotated):
    possibilities = set(range(len(original)))
    for i,letter in enumerate(rotated):
        possibilities &= {(j-i)%len(original) for j in letterPositions[letter]}
        if len(possibilities)==1: #optimization
            break                 #optimization

    if len(possibilities)==1:
        return possibilities.pop()
    else:
        raise Exception('not a rotation')
请注意,如果字符串本身具有旋转,例如
abcabc
,则旋转可能不会完全无序


然后,您可以执行类似于排序的操作(myRotations,key=numIndicesRotated)

一般来说,排序时,您不需要将所有已排序的项并行保存在内存中,您只需要能够对它们进行比较

我的意思是,您可以对字符串旋转开始的索引进行排序(即1='baeba',等等),并提供一种比较方法,该方法将基于该索引比较旋转

虽然复杂性并不比nLog(n)好,但代码应该非常简单。而且,记忆肤色接近你能得到的最佳状态。不知何故,利用排序项目不是随机的知识,可能会给您带来更好的复杂性(但我目前不知道如何做到这一点)。

编辑:Justin Peel指出 只需将字符串附加到自身
bbaeb
即可成为
bbaebbbaeb
(这是解决涉及字符串旋转问题的一个简便技巧)。
查找后缀数组。
遍历它并仅选择小于原始字符串(5)长度的值。 上面字符串的后缀数组

aeb  7
aebbbaeb  2
b  9
baeb  6
baebbbaeb 1
bbaeb 5
bbaebbbaeb 0
eb  8
ebbbaeb  3

S = 7 2 7 6 1 5 0 4 8 3
现在后行程Ans=
2 1 0 4 3

改写 通过使用,您可以在O(n)时间复杂度内解决它。基本上,字符串的后缀数组包含按字典顺序排列的字符串所有后缀的索引。
对于字符串abaeb,按字典顺序排列的后缀为:

abaeb (0)
aeb   (2)
b     (4) 
baeb  (1)
e     (3)
因此后缀数组
S=02413

时间复杂度为O(nlog^2n)的代码在该链接中给出了详细的解释,下一页将对O(n)进行优化。
如果你想让你的代码保持简单,那么使用一个已经回答过的比较运算符是关键。如果您主要关心的是效率,那么请使用o(n)后缀数组构造。

如果您详细说明您的问题,我可以给出更具体的答案。=)注意,OP所说的旋转只是置换的一种特殊情况。这似乎不是OP所问问题的正确答案。OP要求排序的旋转,而不是排序的后缀。我错了吗?对于所使用的示例,结果是相同的,但是使用“bbaeb”将生成不同的结果,用于排序旋转和排序后缀数组。@Justin Peel:很抱歉忽略了这一事实,感谢您指出这一点。我正在编辑解决方案。我在查看维基百科上的Burrows-Wheeler变换后,才解决了这个问题。在谷歌上搜索“排序字符串旋转”,找到了这个页面,上面的答案和我想的一样+1.