Как проверить, является ли двоичное представление целого числа палиндромом?

Как проверить, является ли двоичное представление целого числа палиндромом?

15 ответов


поскольку вы не указали язык, на котором это сделать, вот некоторый код C (не самая эффективная реализация, но она должна проиллюстрировать точку):

/* 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;
}

редактировать исправлено для вашей 10001 вещи.


надеюсь правильно:

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

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

    return m == n;
}

создайте диаграмму 256 линий, содержащую символ, и это бит обратный символ. учитывая 4-байтовое целое число, возьмите первый символ, посмотрите его на графике, сравните ответ с последним символом целого числа. если они отличаются, это не палиндром, если те же самые повторяются со средними символами. если они отличаются, то это не палиндром, а что-то другое.


много хороших решений. Позвольте мне добавить один, который, на мой взгляд, не самый эффективный, но очень читаемый:

/* 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);
}

следующее должно быть адаптировано к любому типу без знака. (Битовые операции над подписанными типами, как правило, чреваты проблемами.)

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

У меня всегда есть функция палиндрома, которая работает со строками, которая возвращает true, если она есть, false в противном случае, например, в Java. Единственное, что мне нужно сделать, это что-то вроде:

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

универсальный вариант:

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

Я думаю, что лучший подход-начать с концов и работать внутрь, т. е. сравнить первый бит и последний бит, второй бит и второй последний бит и т. д., который будет иметь O(N/2), где N-размер int. Если в какой-то момент ваши пары не совпадают, это не палиндром.

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

иногда это хорошо, чтобы сообщить о неудаче тоже;

здесь есть много отличных ответов об очевидном способе сделать это, проанализировав в той или иной форме битовый шаблон. Мне стало интересно, есть ли какие-либо математические решения? Существуют ли свойства палендромных чисел, которыми мы могли бы воспользоваться?

поэтому я немного поиграл с математикой, но ответ должен был быть очевиден с самого начала. Тривиально доказать, что все двоичные палиндромные числа должны быть либо нечетными, либо нулевыми. Это все, на что я был способен.

небольшое исследование не показало такого подхода для десятичных палиндромов, поэтому это либо очень сложная проблема, либо не решаемая с помощью формальной системы. Было бы интересно доказать последнее...


    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. вызовите PalInt (i,1) для двоичных паллиндромов
  2. вызовите PalInt (i,3) для Восьмеричных палиндромов
  3. вызовите PalInt (i,4) для шестнадцатеричных палиндромов

Я знаю, что этот вопрос был опубликован 2 года назад, но у меня есть лучшее решение, которое не зависит от размера слова и всего,

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;

в JAVA есть простой способ, если вы понимаете основной двоичный airthmetic, вот код:

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