我正在复习考试并遇到一个我坚持的练习题。
我需要编写函数find_sequence(unsigned int num, unsigned int patter) {}.
我试过比较num & (pattern << i) == (pattern << i)
和其他类似的东西,但它一直说有一种模式,当没有。我知道为什么会这样做,但我无法解决它。
我使用的num
是unsigned 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,我明白了为什么,但我不知道如何避免它。
答案 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个数字。