2009-05-10 28 views
7

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

+3

Es un palíndromo 10001? ¿O tiene que ser un byte completo 00100100? ¿O tiene que ser un total int- 00000000 00000001 10000000 00000000? – jmucchiello

+0

sí, como 10001. – yesraaj

+3

Entonces '0110' * no es * un palíndromo, porque es realmente' 110', ¿no? Lo que implica que todos los palíndromos distintos de cero son impares. –

Respuesta

11

Puesto 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 debería 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 fijado para su Cosa 10001

+0

Me gusta esta solución por su simplicidad. Está muy claro tanto en código como algorítmicamente. –

+0

¿Qué es WORDSIZE en el código? – EverTheLearner

+0

El número de bits en el entero (o el tipo de datos con el que desee trabajar) – colithium

3

Crea un gráfico de 256 líneas que contiene un char y se invierte un bit de char. dado un entero de 4 bytes, toma el primer carácter, míralo en el gráfico, compara la respuesta con el último carácter entero. si difieren no es palindrome, si son la misma repetición con los caracteres centrales. si difieren, no es palíndromo de lo contrario.

+0

Esto no se escala bien - ¿Vas a utilizar un gráfico de líneas de 2 mil millones para un entero de 32 bits? – rlbond

+2

No necesita hacerlo; solo tiene que comparar bytes a la vez –

+0

Ah, por supuesto. Por supuesto, esto no funciona como lo aclaró. – rlbond

0

Siempre tengo una función palindrome que funciona con Strings, que devuelve verdadero si es falso, de lo contrario, p. Ej. en Java. Lo único que tengo que hacer es algo como:

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

Usted "siempre tiene una función palindrome"? ¿Por qué exactamente? – Hejazzman

+1

Quizás me malinterpreten. Quiero decir que tengo una función palindrome que funciona en Strings, y puedo usarla en todas partes. Piensa una vez, usa siempre. – rapfaria

+3

La pregunta es qué es la implementación de isPalindrome(). Pero, específicamente, con representaciones binarias. – xanadont

0

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 penúltimo bit, etc., que tendrá O (N/2) donde N es el tamaño del int. Si en algún punto tus pares no son iguales, 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; 
} 
+0

No compila: bool right_bit = !!(n & (1 << i); falta un paréntesis de cierre. ¿No se romperá esto si hay ceros a la izquierda, por ejemplo: 17? – dirkgently

+0

Pero es extraño que casi usáramos las mismas versiones (incluso nombres). De hecho, Ejecuté su código contra el mío para determinar las diferencias y los errores del compilador. – dirkgently

+0

Solucionado el error de paren. Asumo, dado que el OP no especificó, que todo el campo de bits del int debe ser un palíndromo, no que ignoremos los ceros a la izquierda Pero ahora que lo mencionas, puede que tenga sentido hacerlo de esa manera. –

0

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"; 
} 
2

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); 
} 
1

El siguiente debería ser adaptable a cualquier tipo sin signo. (Las operaciones de bits en los tipos firmados suelen estar plagadas 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; 
} 
+0

+1; my la respuesta usa el mismo algoritmo, pero en lugar de cambiar una máscara a la izquierda, cambia el valor n a la derecha – Christoph

0

A veces es bueno informar de un error también;

Aquí hay muchas respuestas excelentes sobre la forma obvia de hacerlo, mediante el análisis de alguna forma u otra del patrón de bits. Sin embargo, me pregunté si habría alguna solución matemática. ¿Hay propiedades de números palendrómicos que podamos aprovechar?

Así que jugué un poco con las matemáticas, pero la respuesta debería haber sido obvia desde el principio. Es trivial probar que todos los números palindrómicos binarios deben ser impares o cero. Eso es todo lo que pude lograr con eso.

Una pequeña investigación no mostró tal enfoque para los palindromes decimales, por lo que es un problema muy difícil o no se puede resolver a través de un sistema formal. Puede ser interesante probar lo último ...

+0

"todos los números palindrómicos binarios deben ser impares o cero" 0110 no es impar ni cero, pero puede considerarse un palíndromo en la base 2, eso depende si permites que un palíndromo tenga ceros a la izquierda. – Eloff

+0

Los palíndromos decimales tienen exactamente el mismo enfoque; todos los palíndromos no deben terminar en un 0 o ser 0. – ysth

0
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; 
    } 
16

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; 
} 
+0

¡Agradable! Cantidad mínima de código por ahora. –

0

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; 
0
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. Call PalInt pallindromes (i, 1) para binarios
  2. llamada PalInt (i, 3) para Octal palíndromos
  3. llamada PalInt (i, 4) para Hex palíndromos
0

en Java hay una manera más fácil si usted entiende airthmetic 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(); 
    } 
+0

Esta es una pregunta de la entrevista para probarle las operaciones a nivel de bit, y no tiene la intención de utilizar las funciones de String o StringBuilder – GaRRaPeTa

0
#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; 
} 
1
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; 
} 
+0

Asegúrese de formatear correctamente sus respuestas para que sean legibles. Todo el código debe estar sangrado 4 espacios. ¡Gracias! – mdewitt

Cuestiones relacionadas