Just did this simple application to check whether a string is a palindrome or not
#include <iostream>
#include <string>
using namespace std;
void main()
{
string str;
cout << "Enter a string: "; getline(cin, str);
cout << "Your string is: "; cout << str << endl;
cout << "The reverse of the string is: ";
int counter = 0;
for (int reverseIdx = str.size() - 1, forwardIdx = 0; reverseIdx >= 0 &&
forwardIdx < str.size(); reverseIdx--, forwardIdx++)
{
cout << str[reverseIdx];
if (str[reverseIdx] == str[forwardIdx])
{
counter++;
}
}
cout << endl;
if (counter == str.size())
{
cout << "The string is a Palindrome!" << endl;
}
else
{
cout << "The string is not a Palindrome." << endl;
}
}
I'm getting a string from the user, then printing out the same string (I know it's not needed in such small programs). Then using a for loop to check if every character when reversed is equal to the same character when read normally.
Then using a counter variable I am checking if it's equal to the string size, if it's then it's palindrome.
1 Answer 1
Advice 1: getting the job done the C++ way
You can check whether the input string is a palindrome in one line:
bool is_palindrome(std::string& text) {
return std::equal(text.cbegin(), text.cend(), text.rbegin());
}
For Incomputable has spoken: You can make the above run in the worst case faster by the factor of two:
bool is_palindrome(std::string& text) {
return std::equal(text.cbegin(),
std::prev(text.cend(), text.length() / 2),
text.rbegin());
}
For Deduplicator has spoken: In is_palindrome
, change std::string&
to std::string const&
; this will guarantee that the input string is not modified.
Advice 2
Whatever you implementation of the palindrome checker is, have a dedicated method that does not output the result to std::cout
, but rather returns a boolean indicating whether the input string is a palindrome or not.
Advice 3
void main()
does not compile on modern Xcode; change to int main()
.
Advice 4
Please avoid
using namespace std;
since it pollutes your namespace by importing quite a lot of identifiers/type names.
Advice 5
cout << "Your string is: "; cout << str << endl;
You can write:
cout << "Your string is: " << str << endl;
Alternative implementation
I had this in mind:
#include <algorithm>
#include <iostream>
#include <string>
bool is_palindrome(std::string& text) {
return std::equal(text.cbegin(), text.cend(), text.rbegin());
}
using std::cin;
using std::cout;
using std::getline;
using std::string;
int main()
{
string str;
cout << "Enter a string: ";
getline(cin, str);
cout << "Your string is: " << str << "\n";
cout << "Palindrome: " << std::boolalpha << is_palindrome(str) << "\n";
}
-
\$\begingroup\$ Those are actually solid recommendations! Thanks a lot! \$\endgroup\$saad.sawash– saad.sawash2018年01月03日 19:01:40 +00:00Commented Jan 3, 2018 at 19:01
-
1\$\begingroup\$ @SaadAl-Sabbagh You are most welcome! \$\endgroup\$coderodde– coderodde2018年01月03日 19:02:14 +00:00Commented Jan 3, 2018 at 19:02
-
1\$\begingroup\$ @coderodde, you could also reduce amount of comparisons in the worst case by 2, changing
text.cend()
tostd::prev(text.cend(), text.size() / 2)
. Happy to see you back on C++ tag, btw. \$\endgroup\$Incomputable– Incomputable2018年01月04日 01:44:43 +00:00Commented Jan 4, 2018 at 1:44 -
\$\begingroup\$ @Incomputable Thanks! I have mentioned the suggestion of the C++ Master such as yourself in the first advice. :-) \$\endgroup\$coderodde– coderodde2018年01月04日 15:46:18 +00:00Commented Jan 4, 2018 at 15:46
-
1\$\begingroup\$ Well, your function should either accept a
std::string_view
or at least aconst std::string&
; it doesn't modify the passed argument at all. \$\endgroup\$Deduplicator– Deduplicator2018年01月04日 16:51:22 +00:00Commented Jan 4, 2018 at 16:51