HiveBrain v1.2.0
Get Started
← Back to all entries
patterncMinor

Integer Palindrome Check in C

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
palindromecheckinteger

Problem

This method should check whether a number is a palindrome or not:

typedef enum { false, true } Bool;

Bool is_pal(int n) {
  Bool is_pal_helper(const char *arr, size_t size);

  char temp[12];                         // INT_MIN == '-' + 10 digits (+ null-Terminator)
  sprintf(temp, "%d", n);
  return is_pal_helper(temp, strlen(temp));
}

Bool is_pal_helper(const char *arr, size_t size) {
  if (size <= 1)
    return true;

  if (*arr != *(arr+size-1))
    return false;

  return is_pal_helper(arr+1, size - 2);
}


This was my intuitive solution and I was wondering, if it would be more efficient to keep the number an int, copy and reverse (with modulo and divide-operations) the int and check whether the (reversed) copy is equal to the original int.

Solution

A few notes:

-
Why aren't you using stdbool.h? Use that instead of rolling your own.

-
Why are you using recursion? If you're looking for efficiency, you will use iteration in almost every single circumstance.

-
Why are you constraining yourself to just ints as palindromes if you are already accepting a string with your helper? If you want to stay true to this you could keep your method that you have (with a few changes):

bool isIntPalindrome(int n)
{
    // palindromes only apply to the natural numbers
    if (n  6
    // double that to be safe on weird machines 
    char temp[12];
    sprintf(temp, "%d", n);
    return isPalindrome(temp);
}


Here's my take on your problem, should be faster. I'll provide speed test results in a bit

#include 
#include 
#include 
#include 

bool isPalindrome(char* str)
{
    size_t len = strlen(str);
    for (char *ptr1 = str, *ptr2 = str + len - 1; ptr2 >= ptr1; ptr1++, ptr2--)
    {
        // not super strict check, just test if same lowercase ASCII value
        if(tolower(*ptr1) != tolower(*ptr2)) return false;
    }
    return true;
}

int main(void)
{
    puts(isPalindrome("123454321") ? "true" : "false");
    puts(isPalindrome("12") ? "true" : "false");
    puts(isPalindrome("racecar") ? "true" : "false");
    puts(isPalindrome("test") ? "true" : "false");
}


Output:

$ time ./op
true
false
# had to exclude string examples

real  0m0.025s
user  0m0.011s
sys   0m0.012s

$ time ./syb0rg
true
false
true
false

real  0m0.006s
user  0m0.001s
sys   0m0.002s


Now the resulting time differences aren't that big, but my code didn't try and put the method to its limits to really see how it would perform with something a bit bigger for example. But in the end mine is a bit faster!

Code Snippets

bool isIntPalindrome(int n)
{
    // palindromes only apply to the natural numbers
    if (n < 0) return false;

    // INT_MAX == 32767 + '\0' -> 6
    // double that to be safe on weird machines 
    char temp[12];
    sprintf(temp, "%d", n);
    return isPalindrome(temp);
}
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <ctype.h>

bool isPalindrome(char* str)
{
    size_t len = strlen(str);
    for (char *ptr1 = str, *ptr2 = str + len - 1; ptr2 >= ptr1; ptr1++, ptr2--)
    {
        // not super strict check, just test if same lowercase ASCII value
        if(tolower(*ptr1) != tolower(*ptr2)) return false;
    }
    return true;
}

int main(void)
{
    puts(isPalindrome("123454321") ? "true" : "false");
    puts(isPalindrome("12") ? "true" : "false");
    puts(isPalindrome("racecar") ? "true" : "false");
    puts(isPalindrome("test") ? "true" : "false");
}
$ time ./op
true
false
# had to exclude string examples

real  0m0.025s
user  0m0.011s
sys   0m0.012s

$ time ./syb0rg
true
false
true
false

real  0m0.006s
user  0m0.001s
sys   0m0.002s

Context

StackExchange Code Review Q#113437, answer score: 7

Revisions (0)

No revisions yet.