0

I have an array of integers, where each integer value is a 'group membership' bitmask. For example, array(1, 4, 5) is interpreted as:

  • The first element (1) is a member of Group 0 (i.e. 2**0)
  • The second element (4) is a member of Group 2 (i.e. 2**2)
  • The third element (5) is a member of Groups 0 and 2 (i.e. 2**0 + 2**2)

So, my question is, how can I efficiently count the number of members in each of the groups?

My starting point would be to do something like this:

$count = array();

for ($i=0; $i<64; $i++) {
  $count[$i] = 0;
  $comparator = 2**$i;
  foreach ($array as $value) {
    if ($comparator & $value) $count[$i]++;
  }
}

That seems like a long winded way to go about things. If I have 1,000 elements in the array, I am doing 64 X 1000 iterations.

Is there an easier way to go about this? Using an advanced array technique, for example, or a php extension for bitwise operations?

1 Answer 1

1

If you do not really need to keep 64 groups, and 62 is enough for you (or 30 on 32-bit platform), following code will help you:

  $count = array();
  $data  = array(1, 4, 5, 7);

  foreach ($data as $x)
    for ($i=0, $j = 1; $j <= $x; $i++, $j <<= 1)
        if($x & $j)
            $count[$i]++;

  print "count=";
  print_r($count);
Sign up to request clarification or add additional context in comments.

3 Comments

thanks maxihatop, this is brilliant. One question though, why do I need to reduce the number of groups by two? I can understand reducing by one (for the sign of the integer), but why two?
further to my comment above, I have now tested it and you are right - I can have 62 bit integers fine but as soon as I go to 63 bit, it seems to go into a continuous loop. But why?
Because of max value of single-bit positive is 263. Therefore, all sum of another bits must be less than 2*63. So, highest bit is 262. Please note: my algorithm do not iterate all 62 bits. If input balue is 5, it perform only 3 iterations, and stops on 4th, when $j == 8.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.