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.