Вопрос

Интересная проблема, с которой я столкнулся сегодня: какой самый быстрый способ подсчитать число 1 в n-битном целом числе? Можно ли победить O (n)?

Например:

42 = 0b101010 => 3 ones
512 = 0b1000000000 => 1 one

Ясно, что наивный алгоритм - просто считать. Но есть ли какие-нибудь хитрости, чтобы ускорить его?

(Это всего лишь академический вопрос; при реализации такой стратегии ожидаемого выигрыша в производительности нет.)

Это было полезно?

Решение

См. невероятную статью Bit Twiddling Hacks .

Другие советы

Вероятно, самым быстрым способом на процессорах x86 было бы использовать POPCNT класс инструкций.

Самый быстрый способ (без использования специальных функций процессора или сохранения предварительно рассчитанных ответов) - это И ваше значение со значением - 1 в цикле, пока не будет 0. Число итераций равно числу 1.

Если у вас есть конечное количество бит (например, 32 бита), вы можете предварительно рассчитать его, а затем просто посмотреть значение в массиве.

Несколько более практичный способ - сделать это для каждого байта или слова (занимает всего 256/64 Кбайт), а затем добавить результаты для каждого байта / слова в значение

O (log n) , если вы этого не сделаете за пределами машинных слов и игнорировать тот факт, что каждая машинная операция работает с n битами.

На практике вы должны использовать библиотечные функции вместо того, чтобы самостоятельно разбирать биты, например, Integer.bitCount () в Java.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top