【问题标题】:Strip leading zeroes in binary number in C/C++在 C/C++ 中去除二进制数中的前导零
【发布时间】:2016-06-30 03:02:41
【问题描述】:

给定一个整数,如何去除其二进制表示的前导零?

我正在使用按位运算符来操作它的二进制表示。我想看看一个整数在其二进制表示中是否是回文。我知道那里有不同的解决方案,但我想比较第一位和最后一位,第二位和最后一位,等等。所以,我想知道如何去掉这个 int 的前导 0。

【问题讨论】:

  • 也许是一个愚蠢的问题,但你是如何得到它的二进制表示的?
  • 使用按位运算符来操作其二进制表示。我想看看一个整数在其二进制表示中是否是回文。我知道那里有不同的解决方案,但我想比较第一位和最后一位,第二位和最后一位,等等。所以,我想知道如何去掉这个 int 的前导 0。
  • 您可以尝试将其转换为字符串并使用std::string::find_first_not_of
  • 我可以,但这会超出使用按位运算符进行有效检查的目的。
  • @JKD:评论不是问题。

标签: c++ c binary


【解决方案1】:

您可以使用BitScanForwardBitScanReverse(具体名称因编译器而异)有效地从任一侧修剪(嗯,跳过处理)零。

【讨论】:

  • 嗨 Ben,你能检查一下 BitScanForward 是否真的是 f(x) 用来解决this prefix problem 的函数吗? (见“结论”倒数第二段)。
  • @PeterKrauss:BitScanReverse 对于没有循环的解决方案绝对有用,但您的描述不准确。 BitScanReverse 告诉你要移动多远;它不会返回移位后的数字。
【解决方案2】:

您可以通过查找log base 2 of the number 找到第一个设置的位:

/* from Bit Twiddling Hacks */
static const unsigned int MultiplyDeBruijnBitPosition[32] = 
{
    0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
    8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31
};

uint32_t pos = value;
pos |= pos >> 1;
pos |= pos >> 2;
pos |= pos >> 4;
pos |= pos >> 8;
pos |= pos >> 16;
pos = MultiplyDeBruijnBitPosition[(uint32_t)(pos * 0x07C4ACDDU) >> 27];

或者如果你需要一个面具,只需适应finding the next power of 2

/* adapted from Bit Twiddling Hacks */
uint32_t mask = value - 1;
mask |= mask >> 1;
mask |= mask >> 2;
mask |= mask >> 4;
mask |= mask >> 8;
mask |= mask >> 16;

【讨论】:

  • 0x07C4ACDDU你能引用你的来源吗?
【解决方案3】:

如果您不介意使用字符串并且性能不是问题,您可以这样做:

    #include <bitset>
    #include <string>
    using namespace std;

    // your number
    int N;
    ...

    // convert to a 32 bit length binary string
    string bitstr = bitset<32>(N).to_string();

    // get the substring
    int index = 0;
    string strippedstr;
    for(unsigned int i = 0; i < bitstr.length(); ++i) {
        if(bitstr[i] == '1') {
            index = i;
            break;
        }
    }
    strippedstr = bitstr.substr(index);
   ...

【讨论】:

    【解决方案4】:

    这是How to check if the binary representation of an integer is a palindrome?中发布的答案

    您首先使用此函数反转位:

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

    然后删除尾随零:

    int flipped = flip(n);
    /* shift to remove trailing zeroes */
    while (!(flipped & 0x0001))
        flipped >>= 1;
    

    要回答您关于检查 int 是否为回文的评论,只需将位移位翻转版本与原始版本进行比较:

    return n == flipped;
    

    【讨论】:

    • 我觉得这个效果很差。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-10
    • 1970-01-01
    • 1970-01-01
    • 2015-07-29
    • 2011-08-31
    • 2016-01-15
    • 1970-01-01
    相关资源
    最近更新 更多