Это решение изначально было в двоичном виде и преобразовано в обычную математику в соответствии с указанием запрашивающей стороны.
Это было бы более разумно, поскольку двоичное, по крайней мере, умножение на 2 и деление на 2 должно быть << 1 и >> 1 для скорости, сложения и вычитания, вероятно, не имеют значения, так или иначе.
Если вы передадите маску вместо nBits, и будете использовать битовое смещение вместо умножения или деления, и измените хвостовую рекурсию на цикл, это, вероятно, будет наиболее эффективным решением, которое вы найдете, так как при любом другом вызове это будет ничто но одно добавление, оно будет таким же медленным, как и решение Альнитака, один раз в 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