FAQ: Code Challenge: C++ Functions - Palindrome

I am also curious why it needs to be text,size() - 1? i dont understand where the “extra” character is coming from.

You are referring to

  for (int i = text.size() - 1; i >= 0; i--) {
    reversed_text.push_back(text[i]);
  }

In C++, strings are zero-indexed i.e. the index starts at 0 instead of 1. Suppose you have a string such as text = "Hotel". The text.size() method will give you how many characters are present in the string (5 in this example). Since the index starts at 0 (the first character “H” will be at index 0), so the last character (the 5th character) must be accessed as text[4]. Hence, the need for initializing i = text.size() - 1 in the snippet.

Thank you very much!

The hint solution suggests iterating over a string backwards and constructing a new string that way, making a backwards version of the string, and then comparing to see if the original string and backward string are the same

  1. strings have not been covered, no instruction on how to iterate over a string
  2. no instruction on how to build a new string piece by piece
  3. no instruction on how to compare strings
1 Like

I think that’s because text size starts from 1 and the index starts as 0.

Why does my function not work?

bool is_palindrome(std::string name){

std::string reversedname = name;

int n = 0;

for (int i = name.length(); i >= 0; i–){

reversedname[n] = name[i];

n++;

}

if (name == reversedname){

return true;

}

return false;

}

I posted earlier in the thread

The comment about size() applies to length() as well. So, you need to revisit how you are initializing your for loop for (int i = name.length(); i >= 0; i--).
You should consider making the initialization int i = name.length() - 1;
If you don’t make this modification, you will be trying to access non-existent indices of the string. e.g. If name = “Hotel”, then name[5] won’t give you the last character. name[4] would give you the last character ‘l’.

1 Like

Hey, shouldn’t reversed_text be a vector, because I am confused as to how the push.back() function can work despite the face that reversed_text is a string ? I am new to C++ by the way.

I am just facing this issue today. Well, let’s head over to Stack Exchange more often !

edit: I found the fix, it was supposed to be for (int i=text.size() - 1; i > -1; i–), not for (int i=text.size(); i > -1; i–)

Hi all,

I’m unsure with what’s wrong with my code.

I expect the 1st 2 returns to be true, while the last is false, but they are all returned as false.

What path I wanted to take and code was to do as the hint suggested, which was to declare an empty string, and reverse iterate the argument string, in which each iteration I store the character being iterated on in the reverse string.
Afterwards I put in an if statement in which if the reverse string equals the text, the bool True is printed, else False is printed.
It’s weird because when I modify the function to return the reverse string, the program prints out the text in reverse.

Code:

#include

// Define is_palindrome() here:
std::string is_palindrome(std::string text)
{
std::string reversed_string;

for (int i=text.size(); i > -1; i--)
  {
    reversed_string += text[i];
  }

if (text == reversed_string)
  {
    return "true";
  }
else
  {
    return "false";
  }

}

int main() {

std::cout << is_palindrome(“madam”) << “\n”;
std::cout << is_palindrome(“ada”) << “\n”;
std::cout << is_palindrome(“lovelace”) << “\n”;

}

#include

// Define is_palindrome() here:
bool is_palindrome(std::string text) {

std::string reversed_text="";

for (int i = text.length()-1; i>= 0; i–) {
std::cout<<text[i];//NOT NEED, only for seeing word
reversed_text += text[i];

}
std::cout<<"\n"<<reversed_text<<" “<<text<<” "; //1 mean true - 0 mean false

if (reversed_text == text) {

    return true;

}

return false;

}

int main() {

std::cout << is_palindrome(“madam”) <<"\n";
std::cout << is_palindrome(“ada”) <<"\n";
std::cout << is_palindrome(“lovelace”) <<"\n";

}

Strings appear to behave like vectors in C++

My solution using #include <bits/stdc++.h>. This allows for std::reverse to be used,. A new string, rtext is created in the function and given the initial value of text. std::reverse is used on rtext to flip the string. If statements are used to compare text to rtext. Boolean logic determines if they still match i.e. are palindromes :slight_smile:

Example of how to use std::reverse can be found here: c++ - How to reverse an std::string? - Stack Overflow

Feel free to use my code

#include <iostream>
#include<bits/stdc++.h> 

// Define is_palindrome() here:

bool is_palindrome(std::string text) {

  std::string rtext = text;

  std::reverse(rtext.begin(),rtext.end());

  if (text == rtext) {

    return true;

  }

  else {

    return false;

  }

}

int main() {
  
  std::cout << is_palindrome("madam") << "\n";
  std::cout << is_palindrome("ada") << "\n";
  std::cout << is_palindrome("lovelace") << "\n";
  
}
1 Like

This was the solution I came up with for the palindrome function exercise. Might be a bit of a longer way round, but I liked the idea of coming up with a different way to do it, and it helped cement my knowledge on vectors and for loops.

The return 0 at the end of the function is just there to prevent a compile error in VSCode.

#include <iostream>
#include <vector>

// Define is_palindrome() here:
bool is_palindrome(std::string text) {

std::vector <char> reversed_text;

  for (int i = text.size() - 1; i >= 0; i--) {
    reversed_text.push_back(text[i]);
    
    for (int j = 0; j < reversed_text.size(); j++) {
      if (text[j] == reversed_text[j]) {
        return true;
      }
      else {
        return false;
      }
    } 
  }
  return 0;
}

int main() {
  
  std::cout << is_palindrome("madam") << "\n";
  std::cout << is_palindrome("ada") << "\n";
  std::cout << is_palindrome("lovelace") << "\n";
}

Try testing your code with an input of say “lovelacl”. This isn’t a palindrome, but your code returns 1 or true. Your code is effectively just trying to match the first letter of the string with the last. If the two letters are the same, your code returns true.
You have nested your second for loop within the first for loop. Your existing code doesn’t complete the first for loop before moving on to the second for loop. Consequently, you just push back the last letter of your original input into the reversed_text vector. Then you move on to the second for loop in which you are basically checking whether the first letter of the input matches the last letter.
After fixing the nesting of the for loops, you also need to look more closely at your second loop. You have got return statements in your if…else. This means that your second for loop runs for only one iteration before it encounters a return statement and consequently you exit the function.
As a debugging aid, try editing your code to:

if (text[j] == reversed_text[j]) {
        std::cout << reversed_text.size() << "\n";  
        return true;
      }
      else {
        std::cout << reversed_text.size() << "\n";
        return false;
      }

You will see that by the time you get to the return statements, reversed_text is a vector containing only one element.

2 Likes

Thank you for pointing out my glaringly obvious mistake, right back to the drawing board on this one. Can’t believe I didn’t check it more before posting, I have an idea what might fix it but gonna test it a bit more than I did the last one. If you hadn’t said anything I’d never have realised, cheers!

edit:

Fixed my code, the vectors have the right .size() now and it returns at the right point:

#include <iostream>
#include <vector>

// Define is_palindrome() here:
bool is_palindrome(std::string text) {

std::vector <char> reversed_text;

  int total = 0;
  for (int i = text.size() - 1; i >= 0; i--) {
    reversed_text.push_back(text[i]);
  }
  for (int j = 0; j < text.size() - 1; j++) {
    if (text[j] == reversed_text[j]) {
      total++;
    }
  }
  if (total == reversed_text.size() - 1) {
    return true;
  }
  else {
    return false;
  }
}
int main() {
  
  std::cout << is_palindrome("madam") << "\n";
  std::cout << is_palindrome("ada") << "\n";
  std::cout << is_palindrome("lovelace") << "\n";
}

Will continue working on this to see if I can simplify it a bit but just wanted to show the fix for it:

  • Removed Nested Loop
  • Created comparison value to check for palindrome
  • Put Returns outside the loop so whole for loop runs.
1 Like

As far as I can tell, your function works correctly. It does the job of identifying palindromes successfully. I will just offer a few observations in case you missed them:

  • Your first for loop is correct and will correctly create a vector of characters in the reverse order. But, your second for loop technically doesn’t explicitly iterate over the last character of the original string. You can confirm this by including a cout statement in your loop printing the text[j] character. You will see that the last character is missed by the loop. If you edit your condition to either j <= text.size() - 1 OR you could do j < text.size(). That will iterate over the whole string/vector. You will then also have to edit your if condition to total == reversed_text.size(). If you work through an example like “madam” on paper, you will see why these modifications will work. HOWEVER, all that being said, your function still works fine. Even though you aren’t explicitly iterating over the last character, you have actually implicitly checked the last character. If you have a string and you compare it with its reversed version, you actually don’t need to iterate over all the characters. You just need to check half the string and if no mismatch happens, you have confirmed the string is a palindrome (because the first half of the reversed string is actually the last half of the original string in reverse). So, you don’t need to make the changes I proposed. I just mentioned them in case they escaped your notice.

  • You can also do away with total if you want. If you edit your if condition to text[j] != reversed_text[j] and in the body of your if block you can have it return false. That works because as soon as you see that there is a mismatch of characters, you can immediately exit the function by returning false. Outside your for loop, you can have a return true statement because if the loop was completed without any mismatches, then you have a palindrome.

2 Likes

Thank you for the help, I knew there must have been a way to remove the total variable, I was just so caught up in having it return true that I didn’t think about just ending the loop with return false as soon as there was a mismatch, and just having a return true outside. Have a nice and tidy product thanks to your input:

bool is_palindrome(std::string text) {

std::vector <char> reversed_text;

  for (int i = text.size() - 1; i >= 0; i--) {
    reversed_text.push_back(text[i]);
  }
  for (int j = 0; j < text.size(); j++) {
    if (text[j] != reversed_text[j]) {
      return false;
    }
  }
  return true;
}

int main() {
  
  std::cout << is_palindrome("madam") << "\n";
  std::cout << is_palindrome("ada") << "\n";
  std::cout << is_palindrome("lovelace") << "\n";
}

Thanks for the help, and this has definitely taught me quite a bit, (or at least helped reinforce my knowledge on these subjects).

2 Likes

Here´s my solution: (I followe the indications and it was accepted, but it take me a while and had to check cheatsheet :c)

// Define is_palindrome() here:
bool is_palindrome(std::string text) {
  std::string store = "";
  int n = text.size() - 1;
  for(int i = text.size() - 1; i >= 0; i--){
    store.push_back(text[i]);
  }
  if(text == store){
    return true;
  } else {
    return false;
  }
}

I wrote it same way, in fact it can be shorter :

std::string rtext = text;

this line is not necessary :stuck_out_tongue:

1 Like