简体   繁体   English

查找无符号整数中的某些位模式

[英]Finding certain pattern of bits in an unsigned integer

I am reviewing for an exam and have a practice problem that I'm stuck on. 我正在审查考试,并且遇到了练习上的问题。

I need to write the function find_sequence(unsigned int num, unsigned int patter) {}. 我需要编写函数find_sequence(unsigned int num, unsigned int patter) {}.

I have tried comparing num & (pattern << i) == (pattern << i) and other things like that but it keeps saying there is a pattern when there isn't. 我已经尝试比较num & (pattern << i) == (pattern << i)和其他类似的东西,但是它一直在说没有模式。 I see why it is doing that but I can not fix it. 我知道为什么这样做了,但我无法解决。

The num I'm using is unsigned int a = 82937 and I'm searching for pattern unsigned int b = 0x05 . num我使用的是unsigned int a = 82937和我在寻找模式unsigned int b = 0x05

Pattern:         00000000000000000000000000000101
Original bitmap: 00000000000000010100001111111001

The code so far: 到目前为止的代码:

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

Here is what I have so far. 这是我到目前为止所拥有的。 This keeps returning 3, and I see why but I do not know how to avoid it. 这一直返回3,我知道为什么,但是我不知道如何避免。

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

is bad: - it works only when pattern consists of 1 entirely - you generate at the end of the loop pattern << 31 which is 0 when pattern is even. 不好:-仅当模式完全由1组成时才起作用-在循环pattern << 31的末尾生成,当模式为偶数时为0 Condition will hold every time then. 届时条件将保持不变。

Knowing the length of the pattern would simplify the loop above; 知道模式的长度将简化上面的循环。 just go until 32 - size . 直到32 - size When not given by the API, the length can be calculated either by a clz() function or manually by looping over the bits. 如果API未指定长度,则可以通过clz()函数或通过循环循环位来计算长度。

Now, you can generate the mask as mask = (1u << length) - 1u (note: you have to handle the length == 32 case in a special way) and write 现在,您可以将掩码生成为mask = (1u << length) - 1u (注意:您必须以特殊方式处理length == 32情况)并编写

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

or 要么

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

((num & (pattern << i)) == (pattern << i)) won't give you the desire results. ((num & (pattern << i)) == (pattern << i))不会给您想要的结果。

Let's say you pattern is 0b101 and the value is 0b1111 , then 假设您的模式是0b101 ,值是0b1111 ,那么

   0101   pattern
   1111   value
 & ----
   0101   pattern

Even though the value has not the pattern 0b101 , the check would return true. 即使该值的格式不是0b101 ,检查也将返回true。

You've got to create a mask where all bits of the pattern (until the most significant bit) are 1 and the rest are 0. So for the pattern 0b101 the mask must be b111 . 您必须创建一个掩码,其中模式的所有位(直到最高有效位)均为1,其余均为0。因此,对于模式0b101 ,掩码必须为b111

So first you need to calculate the position of the most significant bit of the pattern, then create the mask and then you can apply (bitwise AND) the mask to the value. 因此,首先需要计算模式最高有效位的位置,然后创建掩码,然后可以将掩码(按位与)应用于值。 If the result is the same as the pattern, then you've found your pattern: 如果结果与模式相同,那么您已经找到了模式:

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

Using this function I get the value 14, where your 0b101 pattern is found in a . 使用这个功能,我得到的值14,你的0b101模式中找到a

In this case you could make a bitmask that 0's out all the spaces you aren't looking for so in this case 在这种情况下,您可以制作一个掩码,使所有不需要的空间都为0

Pattern: 00000000000000000000000000000101 格式:00000000000000000000000000000000000101

Bitmask: 00000000000000000000000000000111 位掩码:00000000000000000000000000000111

So in the case of the number you are looking at 因此,对于您正在查看的数字

Original: 00000000000000010100001111111001 原始:00000000000000010100001111111001

If you and that with this bitmask you end of with 如果你和那个用这个位掩码的那个一起结束

Number after &: 00000000000000000000000000000001 &之后的数字:00000000000000000000000000000001

And compare the new number with your pattern to see if equal. 并将新数字与您的模式进行比较,看是否相等。

Then >> the original number 然后>>原号码

Original: 00000000000000010100001111111001 原始:00000000000000010100001111111001

Right shifted: 00000000000000001010000111111100 右移:00000000000000001010000111111100

And repeat the & and compare to check the next 3 numbers in the sequence. 并重复&进行比较,以检查序列中的下三个数字。

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

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