-1

I'm trying to write a program to solve an ACM problem, and it has to be very fast. A mathematically fast approach to the problem is to use bitwise computations. However, I'm using python and I'm having trouble performing these computations at bit level. The problems are:

  1. Counting the number of 1's and 0's in the bit. For example, how do we calculate the the binary digit 100010 has two 1's and 4 0's. The only approach I can imagine is to convert it to a string and and count them. But this conversion cancels out all the speed gained by working at bit level in the first place.
  2. How to represent a string input describing the binary digit such as '100101' as an actual binary digit in Python? Currently I have a function that converts the bit into an integer and I perform the bitwise operations on the ints.
  3. Is there a bit data type? That is can I receive the input as a bit rather than a string or an int?

I did consider writing a class such as bitSet in C++, but I have a feeling this will not be very fast either. P.S. the binary digits I'm working with can be as large as 1000 bits and I might have to work with a 1000 such binary digits, so efficiency is imperative.

Ragnar
  • 169
  • 7
  • 2
    You seem to be misusing the terms "bit" and "digit"; you should probably look those up so you don't cause confusion when talking to other people, and so the names your code uses make sense. – user2357112 Nov 19 '15 at 00:07
  • Also, if you want to do a lot of bit manipulation quickly, Python isn't going to be an efficient choice. C++ would be much faster at this kind of thing, and as a bonus, it has `std::bitset` right in the standard library. – user2357112 Nov 19 '15 at 00:11
  • One question per question, please. – jwodder Nov 19 '15 at 00:11
  • @user2357112 A bit is a binary digit. Indeed, the term "bit" is short for "binary digit." – saulspatz Nov 19 '15 at 00:37
  • 1
    @saulspatz: Yes, *one* digit. `1`, or `0`, but definitely not `100101`. – user2357112 Nov 19 '15 at 00:42
  • @user237112 Oh, I see what you mean now. I misunderstood you; sorry. – saulspatz Nov 19 '15 at 00:53
  • @user2357112 the problem here isn't really the language of choice, but rather how to represent binary digits in their intrinsic form rather than as a string or an int...or at least what the best possible form is? (if we cannot use it's intrinsic form) – Ragnar Nov 20 '15 at 02:12
  • @user2357112 Furthermore, the term bit or binary digit is synonymous. Using it for 1 or 01 or 001 causes no problem because they are all bits, but of different length. As an analogy, "a", "aa", "aaa" are all strings, but of different length. – Ragnar Nov 20 '15 at 02:20
  • @Ragnar: No, seriously, it doesn't work that way. Maybe you're coming from a language with different pluralization rules or something, but a bit is only `1` or `0`. `001` is 3 bits. – user2357112 Nov 20 '15 at 02:40

1 Answers1

1

Here's a well-known algorithm for counting the one-bits:

def bitCount(x):
    count = 0
    while x != 0:
       count += 1
       x &= (x-1)
    return count

The point is that x-1 has the same binary representation as x, except that the least least significant one-bit is cleared to 0 and all the trailing 0's are set to one. So, setting x = x & (x-1) simply clears the least significant one-bit.

Galax
  • 1,441
  • 7
  • 6
saulspatz
  • 5,011
  • 5
  • 36
  • 47
  • I like your solution, but I'm assuming x is an int or long right. However, I'm working with binary digits that of length possibly 1000. These could easily be stored as strings or in their intrinsic form. But if we convert them to integers or longs, we might exceed the max_int or max_long limits, right? – Ragnar Nov 20 '15 at 02:22
  • python has unlimited precision ints -- there is no such thing as max_long. This should work in python for positive ints of any size. I think it will work for negative ints also. It will certainly work for negative (twos-complement) ints with limited precision arithmetic. This isn't to say it will be the fastest thing to do. As several people have pointed out, if you need speed, write it in C. I was responding to your statement "The only approach I can imagine is to convert it to a string and and count them." – saulspatz Nov 20 '15 at 02:41
  • import sys; sys.maxint; 9223372036854775807 – Ragnar Nov 20 '15 at 05:34
  • python2: >>> import sys; 10*sys.maxint 92233720368547758070L In python 3: AttributeError: module 'sys' has no attribute 'maxint' – saulspatz Nov 20 '15 at 11:23
  • Python 2: `import sys; print type(sys.maxint); print type(sys.maxint*10)` outputs: ` ` – Galax Nov 22 '15 at 17:03