2013-12-19 50 views
-3

所以我试图写一个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回文代码的答案。
在蟒蛇电感情况下只是

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

我如何写一个感性的C++代码回文?

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

+0

不应该是'str.length() - 1'吗?编辑:是的,它应该。我甚至不知道你的代码如何运行。它应该是segfaulting。 – steveg89

+1

@ steveg89:这是UB。 –

回答

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; 
} 
+0

从我的理解你的函数打算返回false如果s [i]和其后的s [i/2]之后的镜像是相似的。正确?。是否s.length()是偶数还是奇数对s.length()/ 2有影响? – Mustafa

+0

它返回's [i]'和's.length() - i - 1]'的false是*不等于*。由于整数除法,偶数或奇数的长度并不重要:5/2 = 2,4/2 = 2.因此,如果你有'11011',0在中间,并且不影响它是回文或不。 –

+0

好吧,我明白了:)。谢谢你的帮助Zac。 – Mustafa

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)))); 
} 
+0

尽管简单(就编码逻辑而言),反向字符串方法相当浪费,因为它必须遍历整个字符串以进行复制,然后再次循环以进行比较。 –

+0

@ Zac Howland,有时编码逻辑方面的简单代码比具有不明显逻辑的复合代码好得多。:) –

+0

确实如此,尽管在这种情况下我很难说直到length()/ 2这个循环,然后比较两者直到你发现不匹配的东西是“具有不明显逻辑的复合代码” - 这正是你要手动确定回文的方法。 –

0

有你应该知道两个关键的事情有关字符串是如何工作的:

  1. 每个引号内的字符串,又名“C-串”或“字符串文字”,由0以上char阵列后跟一个空字符的,例如字符串"bar"具有三个可印刷字符('b''a',& 'r')和一个非印刷字符'\0'(空字符)。因此,在这种情况下,str.c_str()将相当于char str[4] = {'b','a','r','\0'}

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

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

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

+0

这是一个精彩的解释0x4c4a4d ..这是我在发布问题时想到的那种解释。我不知道该怎么感谢你才足够 :) – Mustafa