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

发布于 2024-07-21 04:27:42 字数 27 浏览 5 评论 0原文

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(18

逆蝶 2024-07-28 04:27:43

这里有很多不错的解决方案。 让我添加一个在我看来不是最有效但非常可读的:

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

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);
}
余罪 2024-07-28 04:27:43

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

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

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;
}
私野 2024-07-28 04:27:43
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; 
}
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; 
}
鹿童谣 2024-07-28 04:27:43

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

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

I always have a palindrome function that works with Strings, that returns true if it is, false otherwise, e.g. in Java. The only thing I need to do is something like:

int number = 245;
String test = Integer.toString(number, 2);
if(isPalindrome(test)){
   ...
}
尾戒 2024-07-28 04:27:43

通用版本:

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

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";
}
不气馁 2024-07-28 04:27:43

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

I think the best approach is to start at the ends and work your way inward, i.e. 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. 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;
}
凯凯我们等你回来 2024-07-28 04:27:43

有时报告失败也很好;

这里有很多关于明显的方法的很好的答案,通过以某种形式或其他位模式进行分析。 不过,我想知道是否有任何数学解决方案? 我们可以利用回文数的属性吗?

所以我稍微做了一些数学运算,但答案从一开始就应该是显而易见的。 证明所有二进制回文数必须是奇数或零是很简单的。 这就是我所能做到的。

一些研究表明,十进制回文数没有这种方法,因此它要么是一个非常困难的问题,要么无法通过正式系统解决。 证明后者可能会很有趣......

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

明明#如月 2024-07-28 04:27:43
    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;
    }
    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;
    }
我不会写诗 2024-07-28 04:27:43
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)
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
  2. Call PalInt(i,3) for Octal Palindromes
  3. Call PalInt(i,4) for Hex Palindromes
苏璃陌 2024-07-28 04:27:43

我知道这个问题已经在两年前发布了,但是我有一个更好的解决方案,它不依赖于字长等,

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;

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,

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;
感情洁癖 2024-07-28 04:27:43

在 JAVA 中,如果您了解基本的二进制算术,有一个简单的方法,代码如下:

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

In JAVA there is an easy way if you understand basic binary airthmetic, here is the code:

    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();
     }
不美如何 2024-07-28 04:27:43
#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;
}
#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;
}
是伱的 2024-07-28 04:27:43

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

def CheckBinPal(b):
b=str(bin(b))
如果 b[2:]==b[:1:-1]:
返回真
别的:
返回 False

其中 b 是整数

The solution below works in python:

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

where b is the integer

风渺 2024-07-28 04:27:43

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

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

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

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

x86 有 clz 的指令(有点),但没有反转。 尽管如此,Clang 将发出尽可能最快的代码来在目标架构上进行逆向操作。

If you're using Clang, you can make use of some __builtins.

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

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. Still, Clang will emit the fastest code possible for reversing on the target architecture.

血之狂魔 2024-07-28 04:27:43

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

Javascript Solution

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))
通知家属抬走 2024-07-28 04:27:42

希望正确:

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

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

    return m == n;
}

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;
}
活泼老夫 2024-07-28 04:27:42

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

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

/* 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.

蓝天 2024-07-28 04:27:42

创建一个包含一个字符及其位反转字符的 256 折线图表。
给定一个 4 字节整数,
取出第一个字符,在图表上查看,将结果与整数的最后一个字符进行比较。
如果它们不同,则不是回文,如果相同,则用中间字符重复。
如果它们不同,则不是回文,否则就是。

Create a 256 lines chart containing a char and it's bit reversed char.
given a 4 byte integer,
take the first char, look it on the chart, compare the answer to the last char of the integer.
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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文