Question

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.

Was it helpful?

Solution

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.

OTHER TIPS

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;
}
 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";
  }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top