[英]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.