Help with palindromes?

Write your question here.
I'm almost finished, but can't complete my code to make it work. I want it to take user input of integers and output whether it is a palindrome or not. Then make it a palindrome and say how many integers are in the new number. I also need to make this work with more than a max of 5 digits, but this is what I've only been able to solve.

If you don't know what a palindrome is, it is a number that is the same forward as it is backwards. For example 1221 is a palindrome, but 12214 is not.

My input/output should look like this:
Examples:

input: 121

output: 3 /* 121 is already a palindrome */



input: 12393

output: 7 /* 12393 -> 1239321 */



input: 123

output: 5 /* 123 -> 12321 */
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
  #include <iostream> 
#include <string> 
#include <sstream> 
#include <cstdlib> 
#include <cmath> 

using namespace std; 

const int maxDigits(5); 
int getInt(void); 
bool isPalindrome(int); 
int getShortestLength(int); 
int rev(int); 
unsigned numDigits(int); 

int main(int argc, char *argv[]) { 
bool pal; 
int n; 

cout << "Enter integers: " << maxDigits << endl; 
while (1) { 
while (numDigits(n = getInt()) > maxDigits); 
cout << (((pal = isPalindrome(n)) == true) ? "" : "false "); 
if (pal == false) { 
n = getShortestLength(n); 
cout << endl << n << " is " << ((isPalindrome(n) == true) ? "" : "false ") << "a palindrome"; 
} 
cout << endl << endl; 
} 
return 0; 
} 

bool isPalindrome(int input) { 
return abs(input) == rev(abs(input)); 
} 

int getShortestLength(int n) { 
int z = pow(10, numDigits(abs(n)) - 1), revN = rev(abs(n)); 
return abs(n) * z + (revN % z); 
} 

int rev(int n) { 
int m,y; 
if (n < 10) return n; 
for (m = n % 10,y = n; y >= 10; y /= 10) m *= 10; 
return m + rev(n/10); 
} 

unsigned numDigits(int n) { 
if (abs(n) < 10) return 1; 
return 1 + numDigits(abs(n) / 10); 
} 

int getInt() { 
stringstream ss; 
string line; 
bool inputOk = false; 
int n; 

cout << "> "; 
do { 
getline(cin,line); 
ss.clear(); ss.str(line); 
if ((!(ss >> n)) || (ss.good())) { 
cout << endl << "That cannot be a palindrome" << endl << "> "; 
} else { 
inputOk = true; 
} 
} while (inputOk == false); 
return n; 
} 

You might be overcomplicating this a bit. Here's my attempt, using only <iostream> and <math.h>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <iostream>
#include <math.h>
using namespace std;

int main()
{
    unsigned long long originalnumber, tempnumber, tempnumber2, reversenumber = 0; // unsigned long long will allow for 10-digit inputs
    cout << "Enter an integer (max 10 digits): ";
    cin >> originalnumber;
    tempnumber = originalnumber;
    
    while(tempnumber != 0) // We'll keep dividing tempnumber until it's zero
	{
        int remainder = tempnumber % 10; // Get last digit of tempnumber
        reversenumber = reversenumber * 10 + remainder; // Shift all digits in reversenumber to left, add last digit of tempnumber
        tempnumber /= 10;
    }
    
    if(originalnumber == reversenumber)
    {
		cout << "Your number was a palindrome." << endl;
	}
	else
	{
		cout << "Your number was not a palindrome." << endl;
		tempnumber = originalnumber;
		int numberlength = 1; // Length of originalnumber, tempnumber, reversenumber
		while(tempnumber /= 10) // Keep shifting digits right until tempnumber is 0
		{
			numberlength++;
		}
		tempnumber = originalnumber;
		tempnumber2 = reversenumber;
		
		int digitcut = 0; // How many digits to cut off numbers to arrive at palindrome
		while(tempnumber != tempnumber2) // Keep cutting off digits until we have a palindrome
		{
			digitcut++;
			tempnumber = tempnumber % int(pow(10, numberlength - digitcut)); // Cut first digit off originalnumber
			tempnumber2 = reversenumber / int(pow(10, digitcut)); // Cut last digit off reversenumber
		} // As an example, 12343 and 34321 would each be cut down to 343
		tempnumber = originalnumber;
		tempnumber2 = reversenumber;
		
		tempnumber = tempnumber - (tempnumber % int(pow(10, numberlength - digitcut))); // Cut off all but highest *digitcut* digits
		tempnumber = tempnumber * int(pow(10, digitcut)); // Shift tempnumber left *digitcut* places
		unsigned long long palindrome = tempnumber + tempnumber2;
		cout << "But this is: " << palindrome;
		
		numberlength = 1;
		while(palindrome /= 10) // Get length of final palindrome
		{
			numberlength++;
		}
		cout << " (" << numberlength << " digits)";
	}
}


Hoo boy...that was harder than I thought. I'm very new to programming so it took me 2 hours. I hope this helped!

Sources:
Reversing a number: http://www.programiz.com/cpp-programming/examples/reverse-number
Get digits of int: http://stackoverflow.com/questions/11151548/get-the-number-of-digits-in-an-int
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
#include <sstream>
#include <string>
using std::cout; using std::cin; 
using std::string; using std::stringstream;

string intToStr(const int& num)
{
    stringstream ss;
    ss << num;
    return ss.str();
}

bool isPalindrome(const int& num)
{
    string strNum{ intToStr(num) }, reversed{ strNum.rbegin(), strNum.rend() };
    return strNum == reversed;
}

int main()
{
    cout << "Enter a number: ";
    for(int n{}; cin >> n; ) {
        cout << (isPalindrome(n) ? "Palidrome!" : "Not palindrome!") << "\n\n";
        cout << "Again: ";
    }
}


Enter a number: 1337
Not palindrome!

Again: 1331
Palidrome!

Again: 9999
Palidrome!

Again: 1001
Palidrome!

Again:


http://cpp.sh/7kyd
Consider this:
 12393
3  X Z
9   X
3  . X
2 .
1.

* There is a character in the 2D matrix, if column and row names are identical.
* There are two continuous diagonals from top/left edge to right/bottom edge, marked X and Z

Another representation for X and Z:
X:
12393--
--39321

Z:
12393----
----39321

What did I (almost) do there?
* Took a string and its reverse
* Filled a boolean 2D matrix with match/non-match
* Identified continuous diagonals.
* Took the longest diagonal
* Fill in the missing characters from the other string
You have the right idea logically for checking a palindrome, but you've overcomplicated it by leaving everything as a number. Since palindromes really depend on the string representation of a number rather than it's numeric value, convert the input number to a string first thing and then work with strings from there on out.

Note that there is a general trick here: the internal representation of your data does not have to correspond exactly to the external representation that you're given. Convert data to a form that's convenient for the program.

Returning to the problem, your code doesn't work for input 1232. It returns 1232321 instead of 12321.

Here is the approach that I took. I've removed most of the code in case you want to give this method a try.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// Return true if the suffix of s, starting at pos, is a palindrome.
bool isPal(const string &s, size_t pos = 0);

// Make "s" a palindrome by appending the minimum number of characters
// to the end.
void makePal(string &s)
{
    // Go through the string until you find a suffix that's a
    // palindrome.
    size_t pos;
    // CODE TO FIND THE LONGEST PALINDROMIC SUFFIX GOES HERE

    // The suffix starting at pos is a palindrome.
    // Append the prefix in reverse order
    // CODE TO APPEND GOES HERE
}

int
main(int argc, char *argv[])
{
    // This code takes strings as input instead of numbers.
    string s;
    while (cin >> s) {
        makePal(s);
        cout << s << ' ' << s.size() << '\n';
    }
    return 0;
}

Topic archived. No new replies allowed.