Неважно - черт, я забыл, что он у тебя в строке, а не в int / long / что угодно. Вы все еще можете использовать ту же логику, хотя ... Просто посчитайте в двоичном коде, но используйте только те позиции, которые содержат 1.
Просто мысли вслух.
Давайте возьмем строку 1001
То, что вы хотите, я думаю, это четыре числа 1001, 1000, 0001 и 0000, верно?
Если это так, то вы подсчитываете «одни» позиции.
Один из способов сохранить исходный номер
orig = n;
, а затем начинайте итерацию по этому и каждому нижнему числу
while(n--)
но каждую итерацию игнорируйте те, которые пытаются поставить 1 в позицию 0:
if(n & !orig)
continue;
Если вы ожидаете, что оно будет разреженным - как во многих нулях с очень небольшим числом единиц, вы можете использовать механизм сдвига. Допустим, ваш номер 1000 1001
Обратите внимание, есть три 1, верно? Так что просто посчитай от 000 до 111
Но для каждой итерации распределите биты снова:
n & 0000 0001 | n << 2 & 0000 1000 | n << 5 & 1000 0000 </p>
или другой способ думать об этом:
n & 001 | (n & 010) * 1000 | (n & 100) * 1000 000
Это может быть медленнее, чем другое решение, в зависимости от того, сколько единиц появляется, хотя оно включает внутренний цикл с 1 итерацией для каждой 1 в исходном числе.
Извините за сдвиг между двоичным и десятичным - я могу сделать все это в шестнадцатеричном виде, если хотите:)
Сейчас я не могу придумать шаблон, который напрямую отображает биты без смещения - это будет работать лучше всего.