سؤال

One of our assignments in working with C++ in 1st year programming was to write a function that can check if a number is palindromic or not (e.g 16461). I'd upload my code but I don't even know where to begin when it comes to extracting digits from an integer or checking the number of digits in an integer. Any help or hints would be appreciated!

هل كانت مفيدة؟

المحلول

There are many ways to solve this. I like most the solution that builds the mirror number and checks whether it is identical to the original (even though, it is arguably not the most efficient way). The code should be something like:

bool isPalindrom(int n) {
  int original = n;
  int mirror = 0;
  while (n) {
    mirror = mirror * 10 + n % 10;
    n /= 10;
  }
  return mirror == original;
}

نصائح أخرى

You can use modulo arithmetic (% operator) to extract individual digits. An alternative would be to get the string representation of your number and work with that.

Hints:

  • "Number of digits" is a tricky thing to define, since you can always add 0's on the left-hand side and still have the same number. Read carefully and think carefully about how you want to define this.
  • The digits of an integer are associated with powers of 10 (recall 123 = 1*100 + 2*10 + 3*1), so to extract digits you need to be extracting powers of 10. The key operations are remainder and truncated division. What happens if you do (123 % 10)? How about (123 / 10)? How about ((123 / 10) % 10)?

Best convert the integer into a string first. Testing a string if it is a palindrome is much easier.

#include <sstream>
#include <iostream>
#include <string>

bool isPalindrome(int value)
{
    // convert integer into text
    std::ostringstream oss;
    oss << value;
    std::string valueText = oss.str();
    if (valueText.size()%2==0) {
        return false;
    }
    for (int i = 0; i < (valueText.size()/2); ++i) {
        if (valueText[i]!=valueText[valueText.size()-i-1]) {
            return false;
        }
    }
    return true;
}

int main()
{
    for (int i = 0; i < 100000; ++i) {
        if (isPalindrome(i)) {
            std::cout << i << std::endl;
        }
    }

    return 0;
}

First convert the integer into a std::string:

    std::ostringstream oss;
    oss << value;
    std::string valueText = oss.str();

Now check if the string has a odd number of digits:

    if (valueText.size()%2==0) {
        return false;
    }

If the string has a odd number of digits, test if the digits match:

    for (int i = 0; i < (valueText.size()/2); ++i) {
        if (valueText[i]!=valueText[valueText.size()-i-1]) {
            return false;
        }
    }

Here's a solution that converts the integer to a C-style string and go from there.

#include <iostream>
#include <stdio.h>
#include <string.h>

using namespace std;

bool isPalindrome(int n) {
    char s[256];
    sprintf(s, "%d", n);

    char *p = s, *q = &s[strlen(s) - 1];
    while (*p == *q && p++ < q--) 
        ;

    return (p == q) || (*p == *q);
}

int main() {
    int n = 1644451;
    cout << isPalindrome(n) << endl;

    return 0;
}

If performance is not an issue, and if you can do c++11, an easy to read solution :

template<class T>
bool isPalindrome(T i)
{
    auto s = std::to_string(i);
    auto s2 = s;
    std::reverse(s.begin(), s.end());
    return s == s2;
} 

which is of course much slower than manually going through the digits, but imho is very readable...

call it with:

std::cout << isPalindrome<int>(12321);
std::cout << isPalindrome<int>(1232);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top