This can be easily solved, and you don't need a count-zeroes instruction.
y = x ^ x-1
gives you a string of 1's up to the least-significant 1-bit in x
.
y + 1
is the next individual bit which may be 1 or 0, and
x ^ x-(y+1)
gives you a string of 1's from that bit until the next 1-bit.
Then you can multiply the search pattern by (y+1) and recurse…
I'm working on an algorithm to fetch the strings… hold on…
Yeah… easily solved… while I'm working on that, note there's another trick. If you divide a word into substrings of n
bits, then a series of ≥2n-1
1's must cover at least one substring. For simplicity, assume the substrings are 4 bits and words are 32 bits. You can check the substrings simultaneously to quickly filter the input:
const unsigned int word_starts = 0x11111111;
unsigned int word = whatever;
unsigned int flips = word + word_starts;
if ( carry bit from previous addition ) return true;
return ~ ( word ^ flips ) & word_starts;
This works because, after the addition operation, each bit (besides the first) in flips
corresponding to a 1-bit in in word_starts
equals (by the definition of binary addition)
word ^ carry_from_right ^ 1
and you can extract the carry bits by xor
ing with word again, negating, and ANDing. If no carry bits are set, a 1-string won't exist.
Unfortunately, you have to check the final carry bit, which C can't do but most processors can.