问题
I am trying to write a recursive function that will determine if a string is a palindrome. Here is what I have so far:
int main()
{
string word = "madam";
if (palindrome(word) == true)
cout << "word is a palindrome!" << endl;
else
cout << "word is not a palindrome..." << endl;
return 0;
}
bool palindrome(string word)
{
int length = word.length();
string first = word.substr(0,1);
string last = word.substr((length - 1), 1);
if (first == last)
{
word = word.substr((0 + 1), (length - 2));
cout << word << " " << word.length() << endl; // DEBUGGING
if (word.length() <= 1) return true; // Problem line?
palindrome(word);
}
else
return false;
}
For some reason when the recursive function gets deep enough, and word.length() is less than or equal to 1, It doesn't return true. I can't seem to figure out why. Is it something to do with how recursive functions work, or how I am readjusting the length of word in the line before I commented DEBUGGING?
I am not as talented at C++ as I should be, so please excuse me if my programming seems poor.
回答1:
You are at least missing a return statement here:
if (word.length() <= 1) return true; // Problem line?
return palindrome(word); // ###### HERE !
}
else
return false;
If the length is not 1 you are calling recursively the palindrome
function, ignoring its return value and then returning always false
. With my fix, you will return the result of the palindrome function called with word after removing the first and last letter.
回答2:
The answer by hivert identified your problem but in case you are at all concerned with performance consider using iterators or indices rather than making many string copies. Perhaps something like:
#include <iostream>
template <typename T>
bool palindrome(T begin, T end){
if (end - begin <= 1 )
return true;
--end;
if (*begin != *end)
return false;
++begin;
return palindrome(begin, end);
}
int main() {
std::string word(10000,'a');
if (palindrome(word.cbegin(), word.cend()) == true)
std::cout << "word is a palindrome" << std::endl;
else
std::cout << "word is not a palindrome" << std::endl;
}
But if you want to check a very long string you could get a stack overflow. If you are lucky the compiler might perform tail call optimization. Of course in this case it is easy to remove the recursion and use a loop instead:
#include <iostream>
template <typename T>
bool palindrome(T begin, T end){
while(end - begin > 1) {
--end;
if (*begin != *end)
return false;
++begin;
}
return true;
}
int main() {
std::string word(1000000000,'a');
if (palindrome(word.cbegin(), word.cend()) == true)
std::cout << "word is a palindrome" << std::endl;
else
std::cout << "word is not a palindrome" << std::endl;
}
回答3:
string palindrome(string a, string b)
{
if (a.length() == 1 && a == b)
return "true";
else if (a.substr(0, 1) == b.substr(b.length() - 1, b.length() - 1)) return palindrome(a.substr(1), b.substr(0, b.length() - 1));
else return "false";
}
来源:https://stackoverflow.com/questions/22890946/finding-a-string-palindrome-with-a-recursive-function