简体   繁体   English

如何检查整数的二进制表示是否是回文?

[英]How to check if the binary representation of an integer is a palindrome?

如何检查整数的二进制表示是否是回文?

Hopefully correct:希望正确:

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

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

    return m == n;
}

Since you haven't specified a language in which to do it, here's some C code (not the most efficient implementation, but it should illustrate the point):由于您尚未指定执行此操作的语言,因此这里有一些 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;
}

EDIT fixed for your 10001 thing.编辑修复了你的 10001 件事。

Create a 256 lines chart containing a char and it's bit reversed char.创建一个包含字符的 256 折线图,它是位反转字符。 given a 4 byte integer, take the first char, look it on the chart, compare the answer to the last char of the integer.给定一个 4 字节整数,取第一个字符,在图表上查看,将答案与整数的最后一个字符进行比较。 if they differ it is not palindrome, if the are the same repeat with the middle chars.如果它们不同,则不是回文,如果它们与中间字符相同,则重复。 if they differ it is not palindrome else it is.如果它们不同,则不是回文,否则就是回文。

Plenty of nice solutions here.这里有很多不错的解决方案。 Let me add one that is not the most efficient, but very readable, in my opinion:让我添加一个在我看来不是最有效但非常易读的代码:

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

The following should be adaptable to any unsigned type.以下应该适用于任何无符号类型。 (Bit operations on signed types tend to be fraught with problems.) (有符号类型的位操作往往充满问题。)

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;
}
    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. Call PalInt(i,1) for binary pallindromes为二元回文调用 PalInt(i,1)
  2. Call PalInt(i,3) for Octal Palindromes为八进制回文调用 PalInt(i,3)
  3. Call PalInt(i,4) for Hex Palindromes为十六进制回文调用 PalInt(i,4)

In JAVA there is an easy way if you understand basic binary airthmetic, here is the code:在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;
}

The solution below works in python:下面的解决方案适用于python:

def CheckBinPal(b): b=str(bin(b)) if b[2:]==b[:1:-1]: return True else: return False

where b is the integer其中 b 是整数

If you're using Clang, you can make use of some __builtin s.如果您使用 Clang,则可以使用一些__builtin

bool binaryPalindrome(const uint32_t n) {
  return n == __builtin_bitreverse32(n << __builtin_clz(n));
}

One thing to note is that __builtin_clz(0) is undefined so you'll need to check for zero.需要注意的一件事是__builtin_clz(0)未定义,因此您需要检查零。 If you're compiling on ARM using Clang (next generation mac), then this makes use of the assembly instructions for reverse and clz ( compiler explorer ).如果您使用 Clang(下一代 mac)在 ARM 上进行编译,那么这将使用 reverse 和 clz(编译器资源管理器)的汇编指令。

clz     w8, w0
lsl     w8, w0, w8
rbit    w8, w8
cmp     w8, w0
cset    w0, eq
ret

x86 has instructions for clz (sort of) but not reversing. x86 有 clz(有点)的指令,但没有逆向指令。 Still, Clang will emit the fastest code possible for reversing on the target architecture.尽管如此,Clang 仍会发出最快的代码,以便在目标架构上进行逆向操作。

Javascript Solution Javascript 解决方案

function isPalindrome(num) {
  const binaryNum = num.toString(2);
  console.log(binaryNum)
  for(let i=0, j=binaryNum.length-1; i<=j; i++, j--) {
    if(binaryNum[i]!==binaryNum[j]) return false;
  }
  return true;
}

console.log(isPalindrome(0))

I always have a palindrome function that works with Strings, that returns true if it is, false otherwise, eg in Java.我总是有一个与字符串一起使用的回文函数,如果是,则返回 true,否则返回 false,例如在 Java 中。 The only thing I need to do is something like:我唯一需要做的是:

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

I think the best approach is to start at the ends and work your way inward, ie compare the first bit and the last bit, the second bit and the second to last bit, etc, which will have O(N/2) where N is the size of the int.我认为最好的方法是从末端开始向内工作,即比较第一位和最后一位、第二位和倒数第二位等,这将有 O(N/2) 其中 N是 int 的大小。 If at any point your pairs aren't the same, it isn't a palindrome.如果在任何时候您的对不相同,则它不是回文。

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 generic version:通用版本:

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

Sometimes it's good to report a failure too;有时报告失败也很好;

There are lots of great answers here about the obvious way to do it, by analyzing in some form or other the bit pattern.通过以某种形式或其他形式分析位模式,这里有很多关于明显的方法的很好的答案。 I got to wondering, though, if there were any mathematical solutions?不过,我想知道是否有任何数学解决方案? Are there properties of palendromic numbers that we might take advantage of?是否有我们可以利用的古数的特性?

So I played with the math a little bit, but the answer should really have been obvious from the start.所以我玩了一点数学,但答案从一开始就应该很明显。 It's trivial to prove that all binary palindromic numbers must be either odd or zero.证明所有二进制回文数必须是奇数或零是微不足道的。 That's about as far as I was able to get with it.这就是我所能做到的。

A little research showed no such approach for decimal palindromes, so it's either a very difficult problem or not solvable via a formal system.一些研究表明十进制回文没有这种方法,因此它要么是一个非常困难的问题,要么无法通过正式系统解决。 It might be interesting to prove the latter...证明后者可能很有趣......

I know that this question has been posted 2 years ago, but I have a better solution which doesn't depend on the word size and all,我知道这个问题已经在 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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM