如何修复此c ++回文代码?

时间:2013-12-19 18:06:36

标签: c++

所以我正在尝试编写一个c ++回文程序。到目前为止,我已经提出了两个功能。

void isPal(string str)
{
    int a = 0, b = str.length();
    string checker1 = "", checker2 = "";
    for (; a != str.length(); a++)
        checker1 += str[a];
    for (; b >= 0; b--)
        checker2 += str[b];
    cout << checker1 << "   " << checker2 << endl;
    if (checker1 == checker2)
        cout << "Palindrome baby!" << endl;
    if (checker1 != checker2)
        cout << "Not palindrome!" << endl;      
}

bool isit(string str)
{
            int x = str.length(), counter = 0;

    if (str.length() <= 1)
        return true;
    else
    {
         while (counter != str.length())
         {
             string strNew = str.erase(0, 1);   
             strNew = strNew.erase(strNew.length() - 1);
             string strNewer = str.replace(1, x, strNew);
             return str[0] == str[str.length()] && isit(strNewer);
             counter++;
         }
     }
}

为什么第一个函数总是返回“Not palindrome!” if语句? 我承认第二个是一团糟。当我写作时,我甚至不确定我是否完全理解我的想法。我的意图是提出一个类似的递归Python回文代码的答案 在python中,归纳案例就是

return str[0] == str[-1] and isit( str[1:-1] )

如何编写归纳c ++回文代码?

更新:-4表示初学者的问题!!真的吗? :)

3 个答案:

答案 0 :(得分:2)

检查字符串是否为回文的最简单方法是编写

if ( s == std::string( s.rbegin(), s.rend() ) ) std::cout << "The string is palimdrome." << std::endl;

至于你的递归方法,那么函数看起来可以采用以下方式

bool isPal( const std::string &s )
{
    return ( s.size() < 2 || ( s[0] == s[s.size() - 1] && isPal( s.substr( 1, s.size() - 2 ) ) ) );
}

答案 1 :(得分:1)

您的两个功能都存在很多问题。要测试回文,你只需要遍历字符串一次:

bool isPalindrome(const std::string& s)
{
    for (int i = 0; i < s.length() / 2; ++i)
    {
        if (s[i] != s[s.length() - 1 - i])
        {
            return false;
        }
    }
    return true; // if every element has a mirror, it is a palindrome
}

在你的第二个版本中:

return str[0] == str[str.length()] && isit(strNewer);
counter++;

第二行永远不会被执行。

编写函数的递归版本将是一种浪费,但需要复制子字符串或为函数提供索引:

复制版本

bool isPalindrome(const std::string& s)
{
    if (s.length() <= 1)
        return true;

    if (s[0] != s[s.length() - 1]) // or s.front() != s.back() in C++11
        return false;

    std::string t = s.substr(1, s.length() - 2));
    return isPalindrome(t);
}

索引版

bool isPalindrome(const std::string& s, int index = 0)
{
    if (index <= s.length() / 2)
    {
        return s[index] == s[s.length() - 1 - index] && isPalindrome(s, ++index);
    }
    return true;
}

答案 2 :(得分:0)

关于字符串的工作方式,您应该了解两个关键事项:

  1. 每个引用的字符串,又名“c-string”或“string literal”,由一个0或更多char后跟空字符'\0'的数组组成,例如字符串"bar"有三个可打印的字符('b''a'和&amp; 'r')以及一个非打印字符'\0'(空字符)。因此,str.c_str()在这种情况下等同于char str[4] = {'b','a','r','\0'}

  2. 字符串的length()等于可打印字符的数量。

  3. 第一个迭代器for (; a != str.length(); a++)a=0计算到a=(str.length()-1)(应该如此)。这意味着只有字符串的字符(而不是null-terminus)才会被checker1 += str[a];行追加。在内部,'\0'将自动放在最后。

    第二个迭代器 - for (; b >= 0; b--) - 不能正确映射第一个迭代器。它从b=str.length()降至b=0。从第1点和第2点开始,str[str.length()]处的字符始终为'\0'并不明显。这意味着您的附加字符串checker2首先被赋予空终止符,然后是字符串的其余部分。这意味着当你检查两个不等式时,它会显示为零长度字符串,即""。因此,对于任何非零长度!=,它将始终评估为str,并且您的函数将始终打印"Not palindrome!"