Algorithm 验证字符串是否为旋转回文的有效方法?

Algorithm 验证字符串是否为旋转回文的有效方法?,algorithm,palindrome,Algorithm,Palindrome,旋转回文类似于“1234321”、“3432112”。 简单的方法是将字符串切割成不同的片段,并将它们缩回,然后查看字符串是否是回文。 这需要O(n^2),因为有n个切分,对于每个切分,我们需要O(n)来检查字符串是否是回文。 我想知道是否有比这更好的解决办法。 我想是的,请给我一些建议 谢谢 将字符串连接到自身,然后在新字符串中进行经典回文研究。如果您发现一个回文的长度大于或等于原始字符串的长度,您就知道您的字符串是旋转回文 例如,您可以在34321123432112中进行研究,发现21123

旋转回文类似于“1234321”、“3432112”。 简单的方法是将字符串切割成不同的片段,并将它们缩回,然后查看字符串是否是回文。 这需要O(n^2),因为有n个切分,对于每个切分,我们需要O(n)来检查字符串是否是回文。 我想知道是否有比这更好的解决办法。 我想是的,请给我一些建议


谢谢

将字符串连接到自身,然后在新字符串中进行经典回文研究。如果您发现一个回文的长度大于或等于原始字符串的长度,您就知道您的字符串是旋转回文

例如,您可以在
34321123432112
中进行研究,发现
21123432112
,它比初始字符串长,因此是旋转回文

编辑:正如Richard Stefanec指出的,我的算法在
1121
上失败,他建议我们通过
=
更改长度的
=
测试


编辑2:应该注意的是,找到给定大小的回文显然并不容易。更多信息,请阅读Richard Stefanec post下的讨论。

根据这篇维基百科文章,长度为n的每个字符串在时间O(n)中都可以计算相同大小的数组A,例如:

如果长度为i的S的前缀是回文,则A[i]==1

该算法应可在以下位置找到:

Manacher,Glenn(1975),“一种新的线性时间“在线”算法 查找字符串的最小初始回文”

换句话说,我们可以在线性时间内检查字符串的哪些前缀是回文。我们将使用此结果来解决所提出的问题

每个(非旋转)回文S具有以下形式S=psxs^Rp^R

其中“x”是回文的中心(空字符串或一个字母字符串), “p”和“s”是(可能是空的)字符串,“s^R”表示“s”字符串

从该字符串创建的每个旋转回文具有以下两种形式之一(对于某些p):

  • sxs^Rp^Rp
  • p^Rpsxs^R
  • 这是正确的,因为您可以选择是在回文中间之前还是之后剪切一些子字符串,然后将其粘贴到另一端

    可以看出,子串“p^Rp”和“sxs^R”都是回文,其中一个是偶数长度,另一个是奇数长度

    我们可以使用wikipedia链接中提到的算法创建两个数组A和B。数组A是通过检查哪些前缀是回文,哪些前缀是后缀来创建的。然后我们搜索一个值i,使得a[i]==B[i]==1,使得前缀或后缀的长度为偶数。当建议的字符串是旋转回文且偶数部分是“p^Rp”子字符串时,我们会发现这样的索引,因此我们可以通过将该字符串的一半移动到字符串的另一端来轻松恢复原始回文


    rks对解决方案的一点意见是,此解决方案不起作用,因为对于字符串S=1121,它将创建长度大于或等于S长度的回文的字符串11211121,但它不是旋转回文。如果我们改变解决方案,检查是否存在长度等于S的回文,它会起作用,但我看不到任何直接的解决方案,如何改变搜索最长子串的算法,使其搜索固定长度的子串(len(S))。 (我没有在解决方案下发表评论,因为我是Stackoverflow新手,没有足够的声誉这么做)



    第二句话——我很抱歉没有包括Manacher的算法,如果有人对算法的想法或某些实现有链接,请将其包括在评论中。

    我想提出一个简单的解决方案,只使用常规算法。它不会解决任何更难的问题,但它应该足以完成您的任务。这有点类似于其他两个建议的解决方案,但它们似乎都不够简洁,我无法仔细阅读

    第一步:将字符串连接到自身(
    abvc
    ->
    abvcavc
    ),与所有其他建议的解决方案一样

    第二步:do(使用滚动散列)对新获取的字符串及其反转的字符串执行操作

    第三步:让字符串的长度为
    n
    。对于
    0…n-1
    中的每个索引
    i
    ,使用Rabin-Karp预计算,检查双精度字符串
    [i,i+n-1]
    的子串在恒定时间内是否为回文(基本上,正向和反向子串中获得的值应相等)

    结论:如果第三步发现任何回文,则字符串为旋转回文。如果不是,那么就不是


    PS:Rabin Karp使用散列,即使对于不重合的字符串,冲突也是可能的。因此,如果哈希检查导致验证暴力检查是否相等,则最好进行验证暴力检查。尽管如此,如果Rabin Karp中使用的哈希函数良好,解决方案的摊销速度应保持
    O(n)

    您可以将相同的模式添加到原始模式的末尾。例如,图案为1234321,则可以将相同的图案添加到末端12343211234321。完成此操作后,可以使用KMP或其他子字符串匹配算法来查找所需的字符串。如果匹配,则返回true

    问题:一个数字是回文吗?这
    123217898
    是一个旋转回文吗?(换句话说,它可以剪切两个以上的子字符串)
    123217898
    不是一个旋转回文。这里的O符号是什么?如何搜索回文?与查找给定字符串的最长回文子字符串相同。这可以在线性时间内完成,请看:哦,是的,谢谢你的合作
    #Given a string, check if it is a rotation of a palindrome. 
    #For example your function should return true for “aab” as it is a rotation of “aba”.
    string1 = input("Enter the first string")
    def check_palindrome(string1):
        #string1_list = [word1 for word1 in string1]
        #print(string1_list)
        string1_rotated = string1[1::1] + string1[0]
        print(string1_rotated)
        string1_rotated_palindrome = string1_rotated[-1::-1]
        print(string1_rotated_palindrome)
        if string1_rotated == string1_rotated_palindrome:
            return True
        else:
            return False
    isPalindrome = check_palindrome(string1)
    if(isPalindrome):
        print("Rotated string is palindrome as well")
    else:
        print("Rotated string is not palindrome")