Palindromic number test

Hello, I'm looking for a way to determine whether a number is palindromic (reads the same both ways; 9009; 101; 1001;) or not. I feel like I can do this using arrays, but I want to be as efficient as possible, and using arrays doesn't seem all that efficient. If anyone has any knowledge or hints on how to do this I would be very grateful.

Thanks,
RAWBERRY
Last edited on
I'm not sure if it's possible to do without an array, unless there's a way to read from console input backwards. What I would do is create two pointers pointing at each end of the array (one at index 0 and the other at index size-1) and compare the two while bringing them closer together. If they don't match, return false.
closed account (1yR4jE8b)
I've done this before by first passing the number into a std::stringstream, then just calling the .str() method on it and then just doing normal string palindrome checking.

But if you're getting input from the console, just input it into a string in the first place then you don't need to worry about the conversion.
Last edited on
1
2
3
4
5
6
7
// Obtaining the last digit of your number 
int digit = n%10;
// "push_back" 
number *= 10;
number += digit;
// "pop_back
number /= 10;

No need for array, but I wonder if it is faster.
Last edited on
Is there a way to grab the number of digits within an integer and store them in a variable so I can give the array the correct size?

EDIT: After a bit of searching I found a method using integer division to count the number of digits. Here is the code I came up with, but every time I run it, it crashes.

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
#include <iostream>
using namespace std;

int palindrome_test(int palindrome_check);

int main()
{
    int number;

    cout << "Give me an integer.\n";
    cin >> number;
    cout << "That number has " << palindrome_test(number) << " digits.\n";
}


int palindrome_test(int palindrome_check)
{
    bool palindrome_bool;
    int size;
    int palindrome_number[size];
    int digits;
    int digit_check;
    
    digit_check = palindrome_check;

    do
    {
        digit_check = digit_check / 10;
        digits++;
    } while (digit_check >= 0);

    return digits;
}
Last edited on
You can't declare an array before you get the size. Your program is probably crashing at line 20.
Also
1
2
3
do
        digit_check = digit_check / 10;
while (digit_check >= 0);
infinite loop, the number won't change its sign
I would think that at some point digit_check will be so small that it will be considered == 0, but surely that's not what the OP wants.

I guess a reasonably efficient way would be this:

1
2
3
4
5
6
7
8
9
bool isPalindrome(const std::string& s)
{
    int size = s.size();
    for(int i = 0; i < size / 2; ++i)
    {
        if(s[i] != s[size - 1 - i]) return false;
    }
    return true;
}

And read the number as a string, as darkestfright suggested:

1
2
std::string s;
std::cin >> s;
the solution ne555 gave is the one you're looking for.
his code neither complete, nor correct, but the idea was right.
1
2
3
4
5
6
bool palindrome(int x){
    int t = x, m = 0;
    do m = m*10 + t%10;
    while(t /= 10);
    return m == x;
}
is the shortest I can make it.

whether this is more efficient depends on what your input is. either method itself hardly takes any time (I assume array is faster though). if you are given an array (user input is an array) do the thing with arrays. if you're given an int, do this. conversion is the wasteful part here.
closed account (1yR4jE8b)
What about something like this, it seems much more intutive to me:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
bool isPalindrome(int value)
{
  std::stringstream buff;
  buff << value;
  return isPalindrome(buff.str());
}

bool isPalindrome(std::string toCheck)
{
  for(int i = 0, j = toCheck.length() - 1; i < j; ++i, --j)
  {
    if(toCheck[i] != toCheck[j])
    {
      return false;
    }
  }
  return true;
}

Feh, why not?

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
#include <algorithm>
#include <cctype>
#include <functional>
#include <string>

bool palindrome( unsigned long n )
  {
  unsigned long x = n;
  unsigned long u = 0;
  while (x)
    {
    u *= 10;
    u += x % 10;
    x /= 10;
    }
  return (n == u);
  }

bool palindrome( std::string s )
  {
  s.erase(
    std::remove_if(
      s.begin(),
      s.end(),
      std::not1( std::ptr_fun <int, int> ( std::isalnum ) )
      ),
    s.end()
    );
  std::transform( s.begin(), s.end(), s.begin(), std::ptr_fun <int, int> ( std::tolower ) );
  std::string z = s;
  std::reverse( z.begin(), z.end() );
  return (s == z);
  }

#include <iostream>
#include <limits>
using namespace std;

int main()
  {
  string        s;
  unsigned long n;
  cout << "Palindrome tester\n";
  cout << "Enter nothing to quit.\n";
  while (true)
    {
    cout << "Enter a string> ";
    getline( cin, s );
    if (s.empty()) break;

    cout << "Enter a number> ";
    cin >> n;
    if (!cin) cin.clear();
    cin.ignore( numeric_limits <streamsize> ::max(), '\n' );

    cout << "The string is " << (palindrome( s ) ? "" : "not ") << "a palindrome.\n";
    cout << "The number is " << (palindrome( n ) ? "" : "not ") << "a palindrome.\n\n";
    }
  cout << "Good bye.\n";
  return 0;
  }
I think I've got everything else down, but the digit count is still giving me trouble. I see other solutions here, but shouldn't my first method be performing purely integer division and leaving decimals out of the question? Or am I misinterpreting it? I'm going to move on to other methods, but I'd still like to clear this up.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int main()
{
    int number;
    int digits_a;

    cout << "Give me an integer.\n";
    cin >> number;
    do
    {
        number = number / 10;
        digits_a++;
    } while (number != 0);

    cout << "That number has " << digits_a << " digits.\n";
}
digits_a is uninitialised.
Initialize digits_a to zero first and it should work.
Ugh, I keep making silly mistakes. Thanks guys, for all of your help! I'll post it when I'm finished.
Last edited on
I'm almost done, but I keep getting 2 errors when trying to use the function which checks if the number is a palindrome.

The 2 errors both occur at line 28:

In function 'int main()':
error: invalid conversion from 'int' to 'int*' (Not even using any pointers?)
error: initializing argument 1 of 'bool palindrome_test(int*, int)'
||=== Build finished: 2 errors, 0 warnings ===|


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
#include <iostream>
using namespace std;

bool palindrome_test(int isPalindrome[], int size);
int digit_count(int x);

int main()
{
    int number;
    int length = 0;
    int palindrome[length];
    bool Palindrome_check;

    cout << "Please input an integer.\n";
    cin >> number;

    length = digit_count(number) - 1;
    palindrome[length] = number;
    Palindrome_check = palindrome_test(palindrome[length],length);

    if (Palindrome_check = true)
    {
        cout << "That number is a palindrome\n";
    }
    else
    {
        cout << "That number is not a palindrome\n;";
    }

}


int digit_count(int x)
{
    int digits = 0;

    do
    {
        x /= 10;
        digits++;
    } while (x != 0);

    return digits;
}


bool palindrome_test(int isPalindrome[], int size)
{
    int f = 0; //first number
    int l = size; //last number
    int count;

    for (count = 0; count <= size; count++)
    {
        if (f == l)
        {
            f++;
            l--;
        }
        else
        {
            return false;
        }
    }
    return true;
}


The method ne555 and hamsterman posted works really well, and is super efficient. However, since I had already planned everything out using arrays I would like to finish it that way.

Here's the working result using ne555's and hamsterman's method:
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
#include <iostream>
using namespace std;

bool palindrome(int x);

int main()
{
    int number;
    bool Palindrome_check;

    cout << "Please input an integer.\n";
    cin >> number;

    Palindrome_check = palindrome(number);

    if (Palindrome_check == true)
    {
        cout << "That number is a palindrome\n";
    }
    else
    {
        cout << "That number is not a palindrome\n";
    }
}


bool palindrome(int x)
{
    int t = x, m = 0;
    do
    {
        m = m*10 + t%10;
    } while(t /= 10);

    return m == x;
}

Last edited on
RAWBERRY wrote:
error: invalid conversion from 'int' to 'int*' (Not even using any pointers?)
error: initializing argument 1 of 'bool palindrome_test(int*, int)'

You're using a pointer:

bool palindrome_test(int isPalindrome[], int size);

is equivalent to

bool palindrome_test(int *isPalindrome, int size); // note that int *


I guess line 19 is supposed to be: Palindrome_check = palindrome_test(palindrome,length); // 'palindrome' points to the begin of the array
Topic archived. No new replies allowed.