Pregunta

¿Cómo comprobar si la representación binaria de un número entero es un palíndromo?

¿Fue útil?

Solución

Dado que no se ha especificado un idioma en el que hacerlo, aquí hay algo de código C (no la implementación más eficiente, pero debe ilustrar este punto):

/* flip n */
unsigned int flip(unsigned int n)
{
    int i, newInt = 0;
    for (i=0; i<WORDSIZE; ++i)
    {
        newInt += (n & 0x0001);
        newInt <<= 1;
        n >>= 1;
    }
    return newInt;
}

bool isPalindrome(int n)
{
    int flipped = flip(n);
    /* shift to remove trailing zeroes */
    while (!(flipped & 0x0001))
        flipped >>= 1;
    return n == flipped;
}

Editar fijada para su cosa 10.001.

Otros consejos

Con suerte correcta:

_Bool is_palindrome(unsigned n)
{
    unsigned m = 0;

    for(unsigned tmp = n; tmp; tmp >>= 1)
        m = (m << 1) | (tmp & 1);

    return m == n;
}

Crea un 256 líneas del gráfico que contiene un char y Es bit invertido Char. dado un entero de 4 bytes, tomar el primer carácter, búsquelo en la tabla, comparar la respuesta a la última carbón del entero. si difieren no se palíndromo, si el son los mismos repetición con los caracteres medias. si difieren no es otra cosa que es palíndromo.

Un montón de soluciones agradables aquí. Permítaseme añadir uno que no es el más eficiente, pero muy fácil de leer, en mi opinión:

/* Reverses the digits of num assuming the given base. */
uint64_t
reverse_base(uint64_t num, uint8_t base)
{
  uint64_t rev = num % base;

  for (; num /= base; rev = rev * base + num % base);

  return rev;
}

/* Tells whether num is palindrome in the given base. */
bool
is_palindrome_base(uint64_t num, uint8_t base)
{
  /* A palindrome is equal to its reverse. */
  return num == reverse_base(num, base);
}

/* Tells whether num is a binary palindrome. */ 
bool
is_palindrome_bin(uint64_t num) 
{
  /* A binary palindrome is a palindrome in base 2. */
  return is_palindrome_base(num, 2);
}

Lo siguiente debe ser adaptable a cualquier tipo sin signo. (Operación de bits sobre los tipos firmados tienden a ser lleno de problemas.)

bool test_pal(unsigned n)
{
  unsigned t = 0;

  for(unsigned bit = 1; bit && bit <= n; bit <<= 1)
    t = (t << 1) | !!(n & bit);

  return t == n;
}
int palidrome (int num) 
{ 
  int rev = 0; 
  num = number; 
  while (num != 0)
  { 
    rev = (rev << 1) | (num & 1); num >> 1; 
  }

  if (rev = number) return 1; else return 0; 
}

Siempre tengo una función palíndromo que funciona con cadenas, que devuelve verdadero si lo es, falso en caso contrario, por ejemplo, en Java. Lo único que tengo que hacer es algo como:

int number = 245;
String test = Integer.toString(number, 2);
if(isPalindrome(test)){
   ...
}

Una versión genérica:

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

template <class T>
bool ispalindrome(T x) {
    size_t f = 0, l = (CHAR_BIT * sizeof x) - 1;
    // strip leading zeros
    while (!(x & (1 << l))) l--;
    for (; f != l; ++f, --l) {
        bool left = (x & (1 << f)) > 0; 
        bool right = (x & (1 << l)) > 0;
        //cout <<  left << '\n';
        //cout <<  right << '\n';
        if (left != right) break;
    }
    return f != l;
}       

int main() {
    cout << ispalindrome(17) << "\n";
}

Creo que el mejor enfoque es comenzar en los extremos y su forma de trabajo hacia el interior, es decir, comparar el primer bit y el último bit, el segundo bit y el segundo al último bit, etc, que tendrá O (N / 2 ) donde N es el tamaño de la int. Si en algún momento de sus pares no son lo mismo, no es un palíndromo.

bool IsPalindrome(int n) {
    bool palindrome = true;
    size_t len = sizeof(n) * 8;
    for (int i = 0; i < len / 2; i++) {
        bool left_bit = !!(n & (1 << len - i - 1));
        bool right_bit = !!(n & (1 << i));
        if (left_bit != right_bit) {
            palindrome = false; 
            break;
        }
    }
    return palindrome;
}

A veces es bueno para informar de un fallo también;

Hay un montón de grandes respuestas aquí acerca de la manera obvia de hacerlo, mediante el análisis de una forma u otra el patrón de bits. Tengo que preguntarse, sin embargo, si había alguna soluciones matemáticas? ¿Hay propiedades de los números palendromic que podríamos aprovechar?

Así que juega con las matemáticas un poco, pero la respuesta realmente debería haber sido evidente desde el principio. Es trivial para demostrar que todos los capicúa binarios deben ser par o cero. Eso es por lo que yo era capaz de conseguir con ella.

Un poco de investigación no mostró tal enfoque para palíndromos decimales, por lo que es ya sea un problema muy difícil o no pueden resolver a través de un sistema formal. Podría ser interesante para probar la última ...

    public static bool IsPalindrome(int n) {
        for (int i = 0;  i < 16; i++) {
            if (((n >> i) & 1) != ((n >> (31 - i)) & 1)) {
                return false;
            }
        }
        return true;
    }
bool PaLInt (unsigned int i, unsigned int bits)
{
    unsigned int t = i;
    unsigned int x = 0;
    while(i)
    {
        x = x << bits;        
        x = x | (i & ((1<<bits) - 1));
        i = i >> bits;
    }
    return x == t;
}
  1. Llamada PalInt (i, 1) para pallindromes binarios
  2. Llamada PalInt (i, 3) para Octal Palindromes
  3. Llamada PalInt (i, 4) para Hex Palindromes

Yo sé que esta cuestión se ha publicado hace 2 años, pero tengo una mejor solución que no dependen del tamaño de la palabra y todo,

int temp = 0;
int i = num;
while (1)
{ // let's say num is the number which has to be checked
    if (i & 0x1)
    {
        temp = temp + 1;
    }
    i = i >> 1;
    if (i) {
        temp = temp << 1;
    }   
    else   
    {
        break;
    }
}   

return temp == num;

En Java hay una manera más fácil si usted entiende la aritmética binaria básica, aquí está el código:

    public static void main(String []args){
        Integer num=73;
        String bin=getBinary(num);
        String revBin=reverse(bin);
        Integer revNum=getInteger(revBin);

        System.out.println("Is Palindrome: "+((num^revNum)==0));

     }

     static String getBinary(int c){
         return Integer.toBinaryString(c);
     }

     static Integer getInteger(String c){
         return Integer.parseInt(c,2);
     }

     static String reverse(String c){
         return new StringBuilder(c).reverse().toString();
     }
#include <iostream>
#include <math.h>
using namespace std;
int main()
{
    unsigned int n = 134217729;
    unsigned int bits = floor(log(n)/log(2)+1);
    cout<< "Number of bits:" << bits << endl;
    unsigned int i=0;
    bool isPal = true;
    while(i<(bits/2))
    {
        if(((n & (unsigned int)pow(2,bits-i-1)) && (n & (unsigned int)pow(2,i))) 
                                         ||    
        (!(n & (unsigned int)pow(2,bits-i-1)) && !(n & (unsigned int)pow(2,i))))
        {
            i++;
            continue;
        }
        else
        {
            cout<<"Not a palindrome" << endl;
            isPal = false;
            break;
        }
}

    if(isPal)
        cout<<"Number is binary palindrome" << endl;
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top