A simple algorithm problem

Source: Internet
Author: User

Title: Counts the number of bits in a given number with a value of 1. If it's an array. Solution 1: Traversal algorithm

int getbitcount (unsigned int num) {
    int count = 0;

    while (num) {
        if (num & 0x01)
            count++;

        num = num >> 1;
    }

    return count;
}

The first idea is relatively simple, starting with the last one, whether the comparison is 1, and if 1, the counter plus one. The number of cycles is fixed, 32 times. But there is a place for this method to be aware that the parameter must be unsigned int. Otherwise, if NUM is a negative number, the highest bit will always be set to 1 if it is shifted right in order to guarantee a shift or a negative number, and it will fall into a dead loop. Solution 2: Traversal algorithm (improved)

int getBitCount2 (unsigned int num) {
    int count = 0;

    while (num) {
        count++;

        num = num & (num-1);
    }

    return count;
}

Compared to the first algorithm, we do not have to judge one each time, but by Num & (NUM-1) to judge. After each &, you can set num's lowest bit 1 to 0, then the number of cycles will be reduced to the number of 1 included. Solution 3: Table-checking method

static const unsigned char bitsinbyte[256] = {//0000 0000-0000 0001 0, 1,//0000 0010-0000 0011 1, 2,
    0000 0100-0000 0111 1,2,2,3,//0000 1000-0000 1111 1,2,2,3,2,3,3,4,//0001 0000-0001 1111 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,//0010 0000-0011 1111 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5, 2,3,3,4,3,4,4,5,
    3,4,4,5,4,5,5,6,//0100 0000-0111 1111 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5, 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,//1000 0000-1111 1111 1,2,2,3,2,3,3,4,2 , 3,3,4,3,4,4,5, 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, 3,4,4,5,4,5,5,6,4,5,5,6,5,6, 6,7, 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 4,
5,5,6,5,6,6,7,5,6,6,7,6,7,7,8};
    int getBitCount3 (unsigned int num) {unsigned char n1 = num;
    unsigned char n2 = num >> 8; UnsigNed char n3 = num >> 16;

    unsigned char N4 = num >> 24;
return BITSINBYTE[N1] + bitsinbyte[n2] + bitsinbyte[n3] + bitsinbyte[n4]; }

By defining a bitsinbyte[256] byte array, it contains the number of 1 of the 0000 0000-1111 1111 different numbers. Then divide the number of required statistics into four segments and then calculate the division. solution 4:variable-precision Swar algorithm

unsigned int getBitCount4 (unsigned int num) {
    num = (num & 0x55555555) + ((num >> 1) & 0x55555555);

    num = (num & 0x33333333) + ((num >> 2) & 0x33333333);

    num = (num & 0x0f0f0f0f) + ((num >> 4) & 0x0f0f0f0f);

    num = (num * 0x01010101 >>);

    return num;
}

This algorithm is also often referred to as Hamming weight (Hamming Weight), through a series of displacement and bit operations, you can calculate the Hamming weight of multiple bytes in the constant time, and do not need to use additional memory. Next, the following algorithm is analyzed.

To facilitate the description, we assume that a byte 0xd8-B (binary) 0b11011000 from back to front, followed by 1 to 8 bits, the first bit is 0, and the eighth bit is 1.

Step1: First we can easily know that the number of binary corresponding to the 0x55555555 is 0 b 01010101 01010101 01010101 01010101, and the first operation is equivalent to adding num parity digits. and stored in the odd digits, the sum of which is placed in the even digits if there is a carry.

The step2:0x33333333 corresponding binary number is 0 B 00110011 00110011 00110011 00110011, which adds the odd digits of num to the next odd digit (first plus third, fifth plus seventh), and Num's even digits, Add to the next even digit (second digit plus fourth bit, sixth digit plus eighth digit). If there is a carry, it is saved to the third bit, or the seventh bit.

The step3:0x0f0f0f0f corresponds to a binary number of 0 B 00001111 00001111 00001111 00001111, which adds each byte of NUM, the first four bits, and the last four bits. At this point, the number of 1 in each byte is concentrated in the first four bits. You can now use 0X0M0N0I0J to represent this number, where m,n,i,j represents the number of 1 per byte that the previous num contains.

Step4: It is also the most magical step to add the four numbers of m,n,i,j through this step. Get the final number. In this step, we do not need to translate 0x01010101 into binary. Instead, it takes directly into the operation. By the following formula, we can see the multiplication and then move right 24 bits, which is exactly what we want. Magical ~
Magic.png Operation Speed

algorithm (MS)/data level Ten 10^2 10^3 10^4 10^5 10^6 10^7 10^8
Traverse

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.