找到无符号整数中

时间:2018-03-21 23:30:33

标签: c

我正在复习考试并遇到一个我坚持的练习题。

我需要编写函数find_sequence(unsigned int num, unsigned int patter) {}.

我试过比较num & (pattern << i) == (pattern << i)和其他类似的东西,但它一直说有一种模式,当没有。我知道为什么会这样做,但我无法解决它。

我使用的numunsigned int a = 82937,我正在搜索模式unsigned int b = 0x05

Pattern:         00000000000000000000000000000101
Original bitmap: 00000000000000010100001111111001

到目前为止的代码:

int find_sequence(unsigned int num, unsigned int pattern)
{
        for (int i=0; i<32; i++)
        {
                if ((num & (pattern << i)) == (pattern << i))
                {
                        return i;
                }
        }

        return -9999;
}

int
main()
{
    unsigned int a = 82937;
    unsigned int b = 0x05;

    printf("Pattern: ");
    printBits(b);
    printf("\n");

    printf("Original bitmap: ");
    printBits(a);
    printf("\n");

    int test = find_sequence(a, b);
    printf("%d\n", test);

    return 0;
}

这是我到目前为止所拥有的。这一直不断回归3,我明白了为什么,但我不知道如何避免它。

3 个答案:

答案 0 :(得分:0)

    for (int i=0; i<32; i++)
    {
            if ((num & (pattern << i)) == (pattern << i))

很糟糕: - 仅当模式完全由1组成时才有效 - 当模式为偶数时,在循环pattern << 31结束时生成0。条件将在每次都持有。

知道模式的长度将简化上面的循环;直到32 - size。如果API未给出,则可以通过clz()函数计算长度,也可以通过循环遍历位来计算长度。

现在,您可以将掩码生成为mask = (1u << length) - 1u(注意:您必须以特殊方式处理length == 32案例)并编写

for (int i=0; i < (32 - length); i++)
{
        if ((num & (mask << i)) == (pattern << i))

for (int i=0; i < (32 - length); i++)
{
        if (((num >> i) & mask) == pattern)

答案 1 :(得分:0)

((num & (pattern << i)) == (pattern << i))不会给你带来渴望的结果。

我们假设您的模式为0b101且值为0b1111,那么

   0101   pattern
   1111   value
 & ----
   0101   pattern

即使该值没有模式0b101,检查也会返回true。

你必须创建一个模板的所有位的掩码(直到最多 有效位是1,其余为0.所以对于模式0b101掩码 必须是b111

首先,您需要计算模式最重要位的位置,然后创建 然后你可以将掩码应用(按位AND)到值。如果 结果与模式相同,然后您就找到了自己的模式:

int find_sequence(unsigned int num, unsigned int pattern)
{
    unsigned int copy = pattern;

    // checking edge cases
    if(num == 0 && pattern == 0)
        return 0;

    if(num == 0)
        return -1;

    // calculating msb of pattern
    int msb = -1;
    while(copy)
    {
        msb++;
        copy >>= 1;
    }

    printf("msb of pattern at pos: %d\n", msb);

    // creating mask
    unsigned int mask = (1U << msb + 1) - 1;

    int pos = 0;
    while(num)
    {

        if((num & mask) == pattern)
            return pos;

        num >>= 1;
        pos++;
    }

    return -1;
}

使用此函数,我得到值14,其中找到了0b101模式 a

答案 2 :(得分:-1)

在这种情况下,您可以创建一个位掩码,将0显示在您不想要的所有空格中,所以在这种情况下

模式:00000000000000000000000000000101

位掩码:00000000000000000000000000000111

因此,对于您正在查看的号码

原文:00000000000000010100001111111001

如果您和那个使用此位掩码的人以

结尾

&amp;:00000000000000000000000000000001之后的数字

将新数字与您的模式进行比较,看是否相等。

然后&gt;&gt;原始数字

原文:00000000000000010100001111111001

右移:00000000000000001010000111111100

重复&amp;并比较以检查序列中的后3个数字。