如何检查字符串是不是以回文开头?

Posted

技术标签:

【中文标题】如何检查字符串是不是以回文开头?【英文标题】:How to check if a string start with a palindrome?如何检查字符串是否以回文开头? 【发布时间】:2016-07-23 18:41:00 【问题描述】:

我想检查一个字符串是否以回文子串开头;我正在寻找从我的数组开头开始的最长回文子串。 这是O(n*n) 中的一种简单方法。有没有更聪明的方法?

//not safe for empty string
bool isPalindrome(string s)

    string rev = s;
    std::reverse(rev.begin(), rev.end());
    return rev == s;


int startWithPalindome(const string a)

    int N = a.length();
    for (int len = N; len > 0; len--)
    
        bool isPal = isPalindrome(a.substr(0,len));
        if (isPal)
            return len;
    

    return -1;

编辑:澄清:我知道这段代码可以在很多方面进行改进,做各种调整,但是我有兴趣降低渐近时间复杂度。

【问题讨论】:

在 isPalindrome 中,您不需要反转整个字符串。你知道你是否在中途标记处有回文 所有字符串都以零长度回文开头,所以末尾的 return -1; 似乎不正确。 我会说根据 OP 的规则,你也有一个长度为 1 的回文。如果您从长度 2 开始并继续前进,您将具有相同的时间复杂度,但可能会有更好的平均性能。 @user4581301 - 因为他需要最长回文,所以他需要从末尾开始并向后工作。然而这是真的 - 至少 1 个字符回文总是在那里。除非字符串为空,否则为 0 个字符。 Manacher 的算法是 O(n) 【参考方案1】:

优化 startWithPalindrome()

您的方法是寻找最大可能的回文,并使用蛮力连续减小您考虑的子串的大小,直到找到回文。

您可以轻松地修剪大量比较,方法不是从字符串的总大小开始,而是使用rfind() 查找第一个字符的最后一次出现。然后您可以向后迭代到该字符的上一个位置,依此类推:

int startWithPalindome(const string a)

    if (a.length()>1)
    
        for (int N = a.rfind(a[0]); N!=string::npos && N>0; N= a.rfind(a[0],N-1) ) 
            if ( isPalindrome(a.substr(0,N+1)) )
                return N+1;
        
    
    return -1;

顺便说一句:isPalindrome()的优化

您的isPalindrom() 版本将空字符串或单个字符串视为回文。你可以保持这样,但我建议消除这种情况。

不过,我建议您使用一个小的变体,它不会复制字符串,而只是从头到尾遍历它,因此(几乎)执行最少数量的操作:

bool isPalindrome(string s)

    if (s.length()<2)       // empty strings and singles chars are no palindromes !
        return false;   
    for (auto f=s.cbegin(), r=s.cend()-1; f!=r;  r--) 
        if (*f!=*r)         // if the nth letter from start doesn't match nth from ens
            return false;        // not a palindrom
        if (++f==r)         // if middle of string is between two chars
            break;     
    
    return true;            // we meet in the middle so it's a palindrome 

Online demo

【讨论】:

谢谢这很有用。不过我还是希望能在O(n)时间找到更高效的解决方案

以上是关于如何检查字符串是不是以回文开头?的主要内容,如果未能解决你的问题,请参考以下文章

在 Bash 中,如何检查字符串是不是以某个值开头?

如何检查单词是不是以给定字符开头?

如何检查字符串是不是以多个前缀之一开头?

python:递归检查以确定字符串是不是为回文

如何检查一个字符串是不是以另一个字符串开头 - PHP

检查字符串是不是以 XXXX 开头