该解决方案最初是二进制的,并按照请求者的指定转换为常规数学。
作为二进制更有意义,至少乘以 2 和除以 2 应该是 << 1 和 >> 1 以提高速度,加法和减法可能无关紧要。
如果您传入掩码而不是 nBits,并使用位移而不是乘法或除法,并将尾递归更改为循环,这可能是您会发现的最高效的解决方案,因为其他所有调用都只是一个添加,它只会像 Alnitak 的解决方案一样慢,每 4 次,甚至 8 次调用一次。
int incrementBizarre(int initial, int nBits)
// in the 3 bit example, this should create 100
mask=2^(nBits-1)
// This should only return true if the first (least significant) bit is not set
// if initial is 011 and mask is 100
// 3 4, bit is not set
if(initial < mask)
// If it was not, just set it and bail.
return initial+ mask // 011 (3) + 100 (4) = 111 (7)
else
// it was set, are we at the most significant bit yet?
// mask 100 (4) / 2 = 010 (2), 001/2 = 0 indicating overflow
if(mask / 2) > 0
// No, we were't, so unset it (initial-mask) and increment the next bit
return incrementBizarre(initial - mask, mask/2)
else
// Whoops we were at the most significant bit. Error condition
throw new OverflowedMyBitsException()
哇,结果有点酷。直到最后一秒,我才想到递归。
感觉不对 - 就像有些操作不应该工作,但它们确实是因为你正在做的事情的性质(就像当你在左边的一些位和一些位上操作时感觉你应该遇到麻烦是非零的,但事实证明,除非左边的所有位都为零,否则您永远无法对位进行操作——这是一个非常奇怪的情况,但确实如此。
从 110 到 001 的流程示例(向后 3 到向后 4):
mask 100 (4), initial 110 (6); initial < mask=false; initial-mask = 010 (2), now try on the next bit
mask 010 (2), initial 010 (2); initial < mask=false; initial-mask = 000 (0), now inc the next bit
mask 001 (1), initial 000 (0); initial < mask=true; initial + mask = 001--correct answer