繁体   English   中英

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

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

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

希望正确:

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

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

    return m == n;
}

由于您尚未指定执行此操作的语言,因此这里有一些 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 件事。

创建一个包含字符的 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);
}
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; 
}

以下应该适用于任何无符号类型。 (有符号类型的位操作往往充满问题。)

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. 为二元回文调用 PalInt(i,1)
  2. 为八进制回文调用 PalInt(i,3)
  3. 为十六进制回文调用 PalInt(i,4)

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

下面的解决方案适用于python:

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

其中 b 是整数

如果您使用 Clang,则可以使用一些__builtin

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

需要注意的一件事是__builtin_clz(0)未定义,因此您需要检查零。 如果您使用 Clang(下一代 mac)在 ARM 上进行编译,那么这将使用 reverse 和 clz(编译器资源管理器)的汇编指令。

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

x86 有 clz(有点)的指令,但没有逆向指令。 尽管如此,Clang 仍会发出最快的代码,以便在目标架构上进行逆向操作。

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))

我总是有一个与字符串一起使用的回文函数,如果是,则返回 true,否则返回 false,例如在 Java 中。 我唯一需要做的是:

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

我认为最好的方法是从末端开始向内工作,即比较第一位和最后一位、第二位和倒数第二位等,这将有 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;
}

通用版本:

#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 年前发布了,但是我有一个更好的解决方案,它不依赖于字的大小等等,

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