Program to count number of set bits in an (big) array
Last Updated :
17 Apr, 2023
Given an integer array of length N (an arbitrarily large number). How to count number of set bits in the array?
The simple approach would be, create an efficient method to count set bits in a word (most prominent size, usually equal to bit length of processor), and add bits from individual elements of array.
Various methods of counting set bits of an integer exists, see this for example. These methods run at best O(logN) where N is number of bits. Note that on a processor N is fixed, count can be done in O(1) time on 32 bit machine irrespective of total set bits. Overall, the bits in array can be computed in O(n) time, where 'n' is array size.
However, a table look up will be more efficient method when array size is large. Storing table look up that can handle 232 integers will be impractical.
The following code illustrates simple program to count set bits in a randomly generated 64 K integer array. The idea is to generate a look up for first 256 numbers (one byte), and break every element of array at byte boundary. A meta program using C/C++ preprocessor generates the look up table for counting set bits in a byte.
The mathematical derivation behind meta program is evident from the following table (Add the column and row indices to get the number, then look into the table to get set bits in that number. For example, to get set bits in 10, it can be extracted from row named as 8 and column named as 2),
0, 1, 2, 3
0 - 0, 1, 1, 2 -------- GROUP_A(0)
4 - 1, 2, 2, 3 -------- GROUP_A(1)
8 - 1, 2, 2, 3 -------- GROUP_A(1)
12 - 2, 3, 3, 4 -------- GROUP_A(2)
16 - 1, 2, 2, 3 -------- GROUP_A(1)
20 - 2, 3, 3, 4 -------- GROUP_A(2)
24 - 2, 3, 3, 4 -------- GROUP_A(2)
28 - 3, 4, 4, 5 -------- GROUP_A(3) ... so on
From the table, there is a pattern emerging in multiples of 4, both in the table as well as in the group parameter. The sequence can be generalized as shown in the code.
Complexity:
All the operations takes O(1) except iterating over the array. The time complexity is O(n) where 'n' is size of array. Space complexity depends on the meta program that generates look up.
Code:
C++
#include <bits/stdc++.h>
#include <time.h>
using namespace std;
/* Size of array 64 K */
#define SIZE (1 << 16)
/* Meta program that generates set bit count
array of first 256 integers */
/* GROUP_A - When combined with META_LOOK_UP
generates count for 4x4 elements */
#define GROUP_A(x) x, x + 1, x + 1, x + 2
/* GROUP_B - When combined with META_LOOK_UP
generates count for 4x4x4 elements */
#define GROUP_B(x) \
GROUP_A(x), GROUP_A(x + 1), GROUP_A(x + 1), \
GROUP_A(x + 2)
/* GROUP_C - When combined with META_LOOK_UP
generates count for 4x4x4x4 elements */
#define GROUP_C(x) \
GROUP_B(x), GROUP_B(x + 1), GROUP_B(x + 1), \
GROUP_B(x + 2)
/* Provide appropriate letter to generate the table */
#define META_LOOK_UP(PARAMETER) \
\
GROUP_##PARAMETER(0), \
\
GROUP_##PARAMETER(1), \
\
GROUP_##PARAMETER(1), \
\
GROUP_##PARAMETER(2)\
int countSetBits(int array[], size_t array_size)
{
int count = 0;
/* META_LOOK_UP(C) - generates a table of 256 integers
whose sequence will be number of bits in i-th
position where 0 <= i < 256
*/
/* A static table will be much faster to access */
static unsigned char const look_up[]
= { META_LOOK_UP(C) };
/* No shifting funds (for better readability) */
unsigned char* pData = NULL;
for (size_t index = 0; index < array_size; index++) {
/* It is fine, bypass the type system */
pData = (unsigned char*)&array[index];
/* Count set bits in individual bytes */
count += look_up[pData[0]];
count += look_up[pData[1]];
count += look_up[pData[2]];
count += look_up[pData[3]];
}
return count;
}
/* Driver program, generates table of random 64 K numbers */
int main()
{
int index;
int random[SIZE];
/* Seed to the random-number generator */
srand((unsigned)time(0));
/* Generate random numbers. */
for (index = 0; index < SIZE; index++) {
random[index] = rand();
}
cout << "Total number of bits = "
<< countSetBits(random, SIZE);
return 0;
}
// This is code is contributed by rathbhupendra
C
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
/* Size of array 64 K */
#define SIZE (1 << 16)
/* Meta program that generates set bit count
array of first 256 integers */
/* GROUP_A - When combined with META_LOOK_UP
generates count for 4x4 elements */
#define GROUP_A(x) x, x + 1, x + 1, x + 2
/* GROUP_B - When combined with META_LOOK_UP
generates count for 4x4x4 elements */
#define GROUP_B(x) \
GROUP_A(x), GROUP_A(x + 1), GROUP_A(x + 1), \
GROUP_A(x + 2)
/* GROUP_C - When combined with META_LOOK_UP
generates count for 4x4x4x4 elements */
#define GROUP_C(x) \
GROUP_B(x), GROUP_B(x + 1), GROUP_B(x + 1), \
GROUP_B(x + 2)
/* Provide appropriate letter to generate the table */
#define META_LOOK_UP(PARAMETER) \
GROUP_##PARAMETER(0), GROUP_##PARAMETER(1), \
GROUP_##PARAMETER(1), GROUP_##PARAMETER(2)
int countSetBits(int array[], size_t array_size)
{
int count = 0;
/* META_LOOK_UP(C) - generates a table of 256 integers
whose sequence will be number of bits in i-th
position where 0 <= i < 256
*/
/* A static table will be much faster to access */
static unsigned char const look_up[]
= { META_LOOK_UP(C) };
/* No shifting funds (for better readability) */
unsigned char* pData = NULL;
for (size_t index = 0; index < array_size; index++) {
/* It is fine, bypass the type system */
pData = (unsigned char*)&array[index];
/* Count set bits in individual bytes */
count += look_up[pData[0]];
count += look_up[pData[1]];
count += look_up[pData[2]];
count += look_up[pData[3]];
}
return count;
}
/* Driver program, generates table of random 64 K numbers */
int main()
{
int index;
int random[SIZE];
/* Seed to the random-number generator */
srand((unsigned)time(0));
/* Generate random numbers. */
for (index = 0; index < SIZE; index++) {
random[index] = rand();
}
printf("Total number of bits = %d\n",
countSetBits(random, SIZE));
return 0;
}
Java
import java.util.*;
class Main {
/* Size of array 64 K */
private static final int SIZE = (1 << 16);
/* Meta program that generates set bit count
array of first 256 integers */
/* GROUP_A - When combined with META_LOOK_UP
generates count for 4x4 elements */
private static int[] GROUP_A(int x)
{
return new int[] { x, x + 1, x + 1, x + 2 };
}
/* GROUP_B - When combined with META_LOOK_UP
generates count for 4x4x4 elements */
private static int[] GROUP_B(int x)
{
return new int[] {
GROUP_A(x)[0], GROUP_A(x)[1],
GROUP_A(x)[2], GROUP_A(x)[3],
GROUP_A(x + 1)[0], GROUP_A(x + 1)[1],
GROUP_A(x + 1)[2], GROUP_A(x + 1)[3],
GROUP_A(x + 1)[0], GROUP_A(x + 1)[1],
GROUP_A(x + 1)[2], GROUP_A(x + 1)[3],
GROUP_A(x + 2)[0], GROUP_A(x + 2)[1],
GROUP_A(x + 2)[2], GROUP_A(x + 2)[3],
};
}
/* GROUP_C - When combined with META_LOOK_UP
generates count for 4x4x4x4 elements */
private static int[] GROUP_C(int x)
{
return new int[] {
GROUP_B(x)[0], GROUP_B(x)[1],
GROUP_B(x)[2], GROUP_B(x)[3],
GROUP_B(x + 1)[0], GROUP_B(x + 1)[1],
GROUP_B(x + 1)[2], GROUP_B(x + 1)[3],
GROUP_B(x + 1)[0], GROUP_B(x + 1)[1],
GROUP_B(x + 1)[2], GROUP_B(x + 1)[3],
GROUP_B(x + 2)[0], GROUP_B(x + 2)[1],
GROUP_B(x + 2)[2], GROUP_B(x + 2)[3],
};
}
/* Provide appropriate letter to generate the table */
public static int[] META_LOOK_UP(String parameter)
{
int[] look_up = new int[256];
switch (parameter) {
case "A":
// When combined with META_LOOK_UP generates
// count for 4x4 elements
for (int i = 0; i < 256; i += 2) {
int x = i + (i << 8);
look_up[i] = look_up[i + 1] = GROUP_A(x)[0];
look_up[i + 2] = look_up[i + 3]
= GROUP_A(x)[1];
}
break;
case "B":
// When combined with META_LOOK_UP generates
// count for 4x4x4 elements
for (int i = 0; i < 256; i += 4) {
int x = i + (i << 8);
int[] groupB = GROUP_B(x);
look_up[i] = groupB[0];
look_up[i + 1] = groupB[1];
look_up[i + 2] = groupB[2];
look_up[i + 3] = groupB[3];
}
break;
case "C":
// When combined with META_LOOK_UP generates
// count for 4x4x4x4 elements
for (int i = 0; i < 256; i += 16) {
int x = i + (i << 8);
int[] groupC = GROUP_C(x);
for (int j = 0; j < 16; j++) {
look_up[i + j] = groupC[j];
}
}
break;
default:
throw new IllegalArgumentException(
"Invalid parameter: " + parameter);
}
return look_up;
}
public static int countSetBits(int[] array)
{
int count = 0;
// META_LOOK_UP(C) - generates a table of 256
// integers whose sequence will be number of bits in
// i-th position where 0 <= i < 256 A static table
// will be much faster to access
int[] look_up = META_LOOK_UP("C");
for (int index = 0; index < array.length; index++) {
// Count set bits in individual bytes
count += look_up[array[index] & 0xff];
count += look_up[(array[index] >> 8) & 0xff];
count += look_up[(array[index] >> 16) & 0xff];
count += look_up[(array[index] >> 24) & 0xff];
}
return count;
}
public static void main(String[] args)
{
final int SIZE = (1 << 16);
int[] random = new int[SIZE];
// Generate random numbers.
for (int i = 0; i < SIZE; i++) {
random[i]
= (int)(Math.random() * Math.pow(2, 32));
}
System.out.println("Total number of bits = "
+ countSetBits(random));
}
}
Python3
import random
import time
# Size of array 64 K
SIZE = 1 << 16
# Look-up table generation macros
def GROUP_A(x):
return x, x + 1, x + 1, x + 2
def GROUP_B(x):
return GROUP_A(x) + GROUP_A(x+1) + GROUP_A(x+1) + GROUP_A(x+2)
def GROUP_C(x):
return GROUP_B(x) + GROUP_B(x+1) + GROUP_B(x+1) + GROUP_B(x+2)
def META_LOOK_UP(PARAMETER):
return GROUP_C(PARAMETER)
# Count the number of set bits in an array of integers
def count_set_bits(array):
count = 0
# Look-up table for counting set bits in a byte
look_up = bytearray(META_LOOK_UP(0) + META_LOOK_UP(1) +
META_LOOK_UP(1) + META_LOOK_UP(2))
for value in array:
# Count set bits in individual bytes
count += look_up[value & 0xFF]
count += look_up[(value >> 8) & 0xFF]
count += look_up[(value >> 16) & 0xFF]
count += look_up[(value >> 24) & 0xFF]
return count
# Driver program, generates table of random 64 K numbers
def main():
# Seed to the random-number generator
random.seed(time.time())
# Generate random numbers
random_numbers = [random.randint(0, 2**32-1) for _ in range(SIZE)]
print("Total number of bits =", count_set_bits(random_numbers))
if __name__ == '__main__':
main()
# This is code is contributed by rutikbhosale
JavaScript
/* Size of array 64 K */
const SIZE = (1 << 16);
/* Meta program that generates set bit count
array of first 256 integers */
/* GROUP_A - When combined with META_LOOK_UP
generates count for 4x4 elements */
const GROUP_A = (x) => [x, x + 1, x + 1, x + 2];
/* GROUP_B - When combined with META_LOOK_UP
generates count for 4x4x4 elements */
const GROUP_B = (x) => [
...GROUP_A(x),
...GROUP_A(x + 1),
...GROUP_A(x + 1),
...GROUP_A(x + 2)
];
/* GROUP_C - When combined with META_LOOK_UP
generates count for 4x4x4x4 elements */
const GROUP_C = (x) => [
...GROUP_B(x),
...GROUP_B(x + 1),
...GROUP_B(x + 1),
...GROUP_B(x + 2)
];
/* Provide appropriate letter to generate the table */
const META_LOOK_UP = (PARAMETER) => [
...GROUP_C(0),
...GROUP_C(1),
...GROUP_C(1),
...GROUP_C(2)
];
function countSetBits(array) {
let count = 0;
/* META_LOOK_UP(C) - generates a table of 256 integers whose
sequence will be number of bits in i-th position
where 0 <= i < 256
*/
/* A static table will be much faster to access */
const look_up = new Uint8Array(META_LOOK_UP("C"));
for (let index = 0; index < array.length; index++) {
/* Count set bits in individual bytes */
count += look_up[array[index] & 0xff];
count += look_up[(array[index] >> 8) & 0xff];
count += look_up[(array[index] >> 16) & 0xff];
count += look_up[(array[index] >> 24) & 0xff];
}
return count;
}
/* Driver program, generates table of random 64 K numbers */
function main() {
const random = new Uint32Array(SIZE);
/* Generate random numbers. */
for (let index = 0; index < SIZE; index++) {
random[index] = Math.floor(Math.random() * Math.pow(2, 32));
}
console.log("Total number of bits = " + countSetBits(random));
}
main();
// This is code is contributed by rutikbhosale
C#
using System;
namespace SetBitCount {
class Program {
// Size of array 64 K
const int SIZE = 1 << 16;
// Meta program that generates set bit count
// array of first 256 integers
// GROUP_A - When combined with META_LOOK_UP generates
// count for 4x4 elements
const string GROUP_A = "{0}, {1}, {1}, {2}";
// GROUP_B - When combined with META_LOOK_UP generates
// count for 4x4x4 elements
const string GROUP_B = GROUP_A + ", " + GROUP_A + ", "
+ GROUP_A + ", " + GROUP_A;
// GROUP_C - When combined with META_LOOK_UP generates
// count for 4x4x4x4 elements
const string GROUP_C = GROUP_B + ", " + GROUP_B + ", "
+ GROUP_B + ", " + GROUP_B;
// Provide appropriate letter to generate the table
const string META_LOOK_UP = @" " + GROUP_C + @" ";
static int
CountSetBits(int[] array, int arraySize)
{
int count = 0;
// META_LOOK_UP(C) - generates a table of 256
// integers whose sequence will be number of bits in
// i-th position where 0 <= i < 256 A static table
// will be much faster to access
byte[] lookUpTable
= new byte[256] { " + META_LOOK_UP + @" };
for (int i = 0; i < arraySize; i++) {
// It is fine, bypass the type system
byte[] pData = BitConverter.GetBytes(array[i]);
// Count set bits in individual bytes
count += lookUpTable[pData[0]];
count += lookUpTable[pData[1]];
count += lookUpTable[pData[2]];
count += lookUpTable[pData[3]];
}
return count;
}
// Driver program, generates table of random 64 K
// numbers
static void Main(string[] args)
{
int[] random = new int[SIZE];
// Seed to the random-number generator
Random rand = new Random();
// Generate random numbers.
for (int i = 0; i < SIZE; i++) {
random[i] = rand.Next();
}
Console.WriteLine("Total number of bits = "
+ CountSetBits(random, SIZE));
}
}
}
Time Complexity: O(n)
Auxiliary Space: O(size)
Contributed by Venki.
Similar Reads
Count of pairs in an Array with same number of set bits Given an array arr containing N integers, the task is to count the possible number of pairs of elements with the same number of set bits. Examples: Input: N = 8, arr[] = {1, 2, 3, 4, 5, 6, 7, 8} Output: 9 Explanation: Elements with 1 set bit: 1, 2, 4, 8 Elements with 2 set bits: 3, 5, 6 Elements wit
7 min read
Count number of set bits in a range using bitset Given a large binary number.The task is to count the number of 1's in a given range from L to R (1 based indexing).Examples: Input : s = "101101011010100000111", L = 6, R = 15 Output : 5 s [L : R] = "1011010100" There is only 5 set bits.Input : s = "10110", L = 2, R = 5 Output : 2 Approach: Convert
5 min read
Count total set bits in an array Given an array arr, the task is to count the total number of set bits in all numbers of that array arr. Example: Input: arr[] = {1, 2, 5, 7}Output: 7Explanation: Number of set bits in {1, 2, 5, 7} are {1, 1, 2, 3} respectively Input: arr[] = {0, 4, 9, 8}Output: 4 Approach: Follow the below steps to
5 min read
Python Bin | Count total bits in a number Given a positive number n, count total bit in it. Examples: Input : 13 Output : 4 Binary representation of 13 is 1101 Input : 183 Output : 8 Input : 4096 Output : 13 We have existing solution for this problem please refer Count total bits in a number link. Approach#1: We can solve this problem quick
3 min read
Count of numbers whose 0th and Nth bits are set Given a positive integer N, the task is to count the numbers that can be represented with N bits and whose 0th and Nth bits are set. Examples: Input: N = 2 Output: 1 All possible 2-bit integers are 00, 01, 10 and 11. Out of which only 11 has 0th and Nth bit set.Input: N = 4 Output: 4 Approach: Out o
3 min read
Count unset bits of a number Given a number n, count unset bits after MSB (Most Significant Bit).Examples : Input : 17 Output : 3 Binary of 17 is 10001 so unset bit is 3 Input : 7 Output : 0 A Simple Solution is to traverse through all bits and count unset bits. C++ // C++ program to count unset bits in an integer #include <
7 min read