在32位无符号整数中查找位模式

时间:2009-08-16 15:43:46

标签: c bit-manipulation

我会用一个例子来描述我的问题

给定一个源 - 1010 0010,我想知道字节中存在多少次(计数)模式10(源可以是任何大小的8,16,24或32位)。

我希望找到计数的函数是通用的。用户应该能够提供自己的模式即。 1000,101等

我想补充一点,我试图解决这个问题。下面是代码片段(In C语言)

我使用的逻辑是使用Ex-OR运算,这样如果模式匹配ex-or的结果将为0。

unsigned int FindPattern (unsigned int u32Number, unsigned int u32Pattern)
{

    unsigned int count = 0;
    unsigned int u32Temp = 0;

    while (0 != u32Number)
    {
        /* How can I turn off (0) all the bits except bits which represent pattern 
         * For example if pattern is 3 bits then the all the bits except the last 3 
         * bits should be 0. */

        if(!(u32Number ^ u32Pattern))
        {
            count++;
        }

    u32Number = u32Number >> 1;
    }

    return count;
}

6 个答案:

答案 0 :(得分:2)

一个非常奇怪的问题,基本解决方案:

Starting from the right most bit
Find a 0, Set a marker
Go left 1 bit
If the bit is a 1, Increment the Number of 10's, Move Left 1 Bit
If the bit is a 0, Unset the Previous Marker, Set the Marker
Repeat until you have reached the beginning of the string

希望有所帮助。

答案 1 :(得分:2)

试试这个:

#include <stdio.h>

int main(void)
{

    unsigned int number = 0xa2;
    unsigned int pattern = 0x02;
    unsigned int pattern_mask = 0x03;

    int count = 0;
    while(number > 0) {

        if( !((number ^ pattern) & pattern_mask) ) {
            ++count;
            printf("%x\n", number);
        }

        number >>= 1;

    }

    printf("\ncount:  %d\n", count);

    return 0;
}

假设您对引导零不感兴趣。

pattern_mask可以计算出来。

答案 2 :(得分:1)

#include <iostream>
using namespace std;

int count(long haystack, long needle, unsigned int needle_bits)
{
    int total_bits = 8 * sizeof(haystack);

    long excludepattern = 1; for (unsigned int j = 1; j < needle_bits; j++) excludepattern += excludepattern * 2; //generate mask

    int count = 0;

    for (unsigned int i = 0; i < total_bits - needle_bits; i++)
    {
        long pattern = haystack >> i;
        pattern &= excludepattern; //mask the haystack so only the used bits count

        if (pattern == needle) count++;
    }

    return count;
}

int main()
{
    long haystack = 55; //110111
    long needle1 = 2; //10
    long needle2 = 3; //11;

    cout<<"10 occurs "<<count(haystack,needle1,2)<<" times in 110111."<<endl;
    cout<<"11 occurs "<<count(haystack,needle2,2)<<" times in 110111."<<endl;

    system("PAUSE");
    return 0;
}

我很抱歉这是在C ++中,而不是C,但这对于count函数无关紧要,因为它不使用C ++特定的构造。

预期产量: 10在110111中发生1次。 11在110111发生了3次。

答案 3 :(得分:1)

你的模式总是以1开头吗?如果没有,则必须以某种方式指定长度。如果是这样,好吧,这有点像家庭作业问题,但我向你推荐以下表达方式:

 b <<= 1
 b < pat
 b - 1

答案 4 :(得分:0)

这是一个天真的C#解决方案,您可以从中收集一些想法来实现您的C作业。


        static void Main(string[] args)
        {
            String p = "10";            
            int s = 0x0A0A0C0C;

            Console.WriteLine(CountBitPattern(p, s));
            Console.ReadLine();
        }

        // count the occurences of bit pattern p - in - int s
        static int CountBitPattern(String p, int s)
        {
            String t = "";

            for (int i = 31; i >= 0; i--)
            {
                if ((s & (1 << i)) > 0)
                    t += '1';
                else
                    t += '0';
            }

            int c = 0;
            int n = 0;
            int r = 0;
            while (r > -1)
            {
                r = t.IndexOf(p, n);
                if (r > -1)
                    c++;
                n = r + 1;
            }

            return c;
        }

答案 5 :(得分:0)

这是C中的解决方案。任何人都可以帮助简化“if”声明吗?

int bit_pattern_exists (int num, int pattern)
{
int i= 0, count = 0;

int len_num=0;
int len_pattern=0;
int p = pattern;
int temp = num;

/* count the number of bits in the pattern */
while (p) {
    len_pattern++;
    p = p >> 1;
}   

/* count the number of bits in the number */
while (temp) {
    len_num++;
    temp  = temp >> 1;
}   

if (len_num<len_pattern)
    return FALSE;

i = 0 ; 

while (i < len_num) {
    if ((pattern << i) == (((~(~0 << len_pattern))<<i)&num)) {
        count++;
    }   

    i++;

    if (len_pattern > len_num -i) 
        break;
}   

return count;
}