I am looking for an efficient algorithm to find the longest run of zeros in a binary string. My implementation is in Python 2.7, but all I require is the idea of the algorithm.
For example, given '0010011010000', the function should return 4.
|
I don't think there is anything better than a single pass over the string, counting the current sequence length (and updating the maximum) as you go along. If by "binary string" you mean raw bits, you can read them one byte at a time and extract the eight bits in there (using bit shifting or masking). That does not change the overall algorithm or its complexity. |
|||||||||||||||||||||
|
It should be possible to beat the obvious algorithm. The idea is, if you aleready have a run of 0s of length N and you see two 1s at no more than N positions apart, you don't need to check any positions in between. So check a candidate sequence of zeroes from the end rather than from the beginning. In the very worst case you will just check all the elements, just as in the naïve method, but on the average it will be less than that. So the algo goes like this (pseudocode, untested)
|
||||
|
To find the largest run of consecutive zeros in a binary string, I suggest the following outline:
You should separately handle the case where binaryString ends in zero. Add that part to the provided outline and you are done. The complexity of this approach is linear in the length of binary string. |
|||||||||
|
It depends on what you mean by efficient. If your intent is to minimise runtime, you'll basically have to go over the string character by character, analysing the runs of consecutive zeros and keeping track of the longest, something like:
If you're talking about programmer efficiency, just do:
instead. It won't necessarily run the fastest but it'll free you up to have more time, perhaps to be used in analysing whether you even need raw speed for this operation. It'll also almost certainly be less prone to bugs to to its length. As to whether you need the speed, consider this. With a 25M string, the character-by-character method takes 2.826 seconds CPU time for a million iterations. The So, unless your string are a lot longer than 25M or you need to do it much more than a million times, it's not going to make a lot of difference, and I'd tend to opt for the method that's easier for me as a developer. Addendum: after espousing how irrelevant differential performance is here, I feel a bit hypocritical mentioning that another method shown by John La Rooy in a comment actually seems to be a bit faster than both of mine. But, for completeness, I'll suffer the slings and arrows to point that one out as well:
That appears to average out at about 1 Those figures are averages of five runs, in my environment, and I make no guarantee they'll hold up anywhere else. If you've ever been involved in optimisation efforts, you should know that it should be measured in your actual environments, rather than depending on the say-so of some random (but extremely good-looking) person on the internet :-) |
|||||||||||||
|
Okay, as someone mentioned, it the type is String, then I think you cannot escape O( |N| ) which is I/O time. I here just want to say it it is an integer, then you may do a bit faster, for example:
Ignore the printing part, I think it is O(lg N)? (Caution: as this is handling integer, no padding zero is considered, it should not be hard though) |
||||
|
A compiled regex might be decently fast, but I haven't really tested it. Nevertheless:
|
|||
|