Главная страница » Напишите функцию которая находит количество единиц в двоичной записи числа

Напишите функцию которая находит количество единиц в двоичной записи числа

  • автор:

Ошибка сервера в приложении ‘/’.

Описание: На сервере возникла ошибка приложения. Текущая пользовательская настройка ошибок для этого приложения не позволяет удаленно просматривать сведения об ошибке данного приложения (из соображений безопасности). Однако, сведения можно просматривать в браузерах, запущенных на локальном сервере.

Сведения: Для разрешения просмотра сведений данного сообщения об ошибке на локальном сервере создайте тег <customErrors> в файле конфигурации "web.config", который находится в корневом каталоге текущего веб-приложения. В теге <customErrors> следует задать атрибут "mode" со значением "Off".

Примечания: Отображаемую в данный момент страницу ошибок можно заменить на пользовательскую страницу ошибок, изменив атрибут "defaultRedirect" тега конфигурации <customErrors> приложения таким образом, чтобы он содержал URL-адрес пользовательской страницы ошибок.

Подсчитайте количество единиц в двоичном представлении

эффективный способ подсчета числа 1s в двоичном представлении числа в O (1), Если у вас достаточно памяти для игры. Это вопрос интервью, который я нашел на онлайн-форуме, но у него не было ответа. Может кто-нибудь предложить что-то, я не могу придумать способ сделать это в O(1) Время?

21 ответов:

Это вес Хэмминга проблема, ака подсчет населения. Ссылка упоминает эффективные реализации. Цитирование:

с неограниченной памятью мы могли бы просто создать большую таблицу поиска веса Хэмминга каждого 64-битного целого числа

у меня есть решение, которое подсчитывает биты в O(Number of 1’s) время:

в худшем случае (когда число 2^n — 1, Все 1 в двоичном формате) он будет проверять каждый бит.

изменить: Просто нашел очень хороший алгоритм постоянного времени, постоянной памяти для bitcount. Вот оно, написано на C:

вы можете найти доказательство своей правоты здесь.

обратите внимание на то, что: n&(n-1) всегда устраняет наименее значимый 1.

следовательно, мы можем написать код для вычисления количества 1 следующим образом:

сложность программы будет: число 1 в n (которое постоянно

Я видел следующее решение с другого сайта:

Это будет самый короткий ответ в мою жизнь так: таблица подстановки.

видимо, мне нужно немного объяснить:» если у вас достаточно памяти, чтобы играть » означает, что у нас есть вся необходимая память (неважно, техническая возможность). Теперь вам не нужно хранить таблицу поиска более одного или двух байтов. Хотя технически это будет Ω(log(n)), а не O(1), просто чтение числа, которое вам нужно, — это Ω(log (n)), поэтому, если это проблема, то ответ, невозможно — что еще короче.

какой из двух ответов они ожидают от вас на интервью, никто не знает.

есть еще один трюк: в то время как инженеры могут взять число и говорить о Ω(log(n)), где n-число, компьютерные ученые скажут, что на самом деле мы должны измерять время работы как функцию a длина ввода, поэтому то, что инженеры называют Ω(log(n)), на самом деле Ω(k), где k-количество байтов. Тем не менее, как я уже говорил, просто чтение числа-это Ω(k), поэтому мы не можем сделать лучше этого.

функция принимает int и возвращает количество единиц в двоичном представлении

ниже приводится решение C с использованием битовых операторов:

следующее решение Java с использованием полномочий 2:

  1. мы можем просто подсчитать набор бит (1), используя __строение_popcount().

    int numOfOnes(int x)

  2. цикл через все биты в целое число, проверьте, если бит установлен, и если это затем увеличить переменную count.

    int hammingDistance(int x)

есть только один способ, который я могу придумать, чтобы выполнить эту задачу в O(1). то есть «обмануть» и использовать физическое устройство (с линейным или даже параллельным программированием я думаю, что предел-O(log(k)), где k представляет количество байтов числа).

однако вы можете очень легко представить себе физическое устройство, которое соединяет каждый бит с выходной линией с напряжением 0/1. Затем вы можете просто прочитать в электронном виде общее напряжение на линии «суммирования» в O(1). Это было бы вполне легко сделать эту основную идею более элегантной с некоторыми основными элементами схемы для получения выхода в любой форме, которую вы хотите (например, двоичный кодированный выход), но основная идея одна и та же, и электронная схема будет производить правильное состояние выхода в фиксированное время.

Я предполагаю, что есть также возможные возможности квантовых вычислений, но если нам позволят это сделать, я бы подумал, что простая электронная схема-это более простое решение.

Я на самом деле сделал это, используя немного ловкости рук: одной таблицы поиска с 16 записями будет достаточно, и все, что вам нужно сделать, это разбить двоичный rep на кусочки (4-битные кортежи). Сложность на самом деле O(1), и я написал шаблон C++, который был специализирован на размере целого числа, которое вы хотели (в # битах). делает его постоянным выражением вместо неопределенного.

fwiw вы можете использовать тот факт, что (i & — i) вернет вам LS один бит и просто цикл, зачистка выключайте lsbit каждый раз, пока целое число не станет нулем — но это старый трюк с четностью.

Я пришел сюда, имея большую веру, что я знаю красивое решение этой проблемы. Код в C:

но после того, как я провел небольшое исследование по этой теме (читайте другие ответы:)) я нашел 5 более эффективных алгоритмов. Люблю так!

есть даже инструкция CPU, разработанная специально для этой задачи: popcnt . (упоминается в ответ)

описание и бенчмаркинг многих алгоритмов вы можете найти здесь.

ниже метод может подсчитать количество 1s в отрицательных числах, а также.

однако число, подобное -1, представлено в двоичном виде как 1111111111111111111111111111111111 и поэтому потребует много сдвига. Если вы не хотите делать так много сдвигов для небольших отрицательных чисел, другой способ может быть следующим:

в python или любом другом преобразовании в строку bin затем разделите ее с помощью «0», чтобы избавиться от 0, затем объедините и получите длину.

С использованием строковых операций в JS можно сделать следующим образом:

или

Я должен был гольф это в Руби и в конечном итоге с

использование :

l[2**32-1] # returns 32

очевидно, не эффективно, но делает трюк 🙂

двумя способами:

где binaryValue-это двоичная строка, например: 1100

Напишите функцию которая находит количество единиц в двоичной записи числа

______________
Название темы по правилам форума должно адекватно отражать суть решаемой задачи/проблемы.
В последующем, темы с названием наподобие "C++" будут закрываться или удаляться,
а автор такой темы будет получать штрафные баллы.
Учтите это на будущее.
__________________

Код нужно оформлять по правилам:
тегом [CODE]..[/СODE] (это кнопочка с решёточкой #)
Не забывайте об этом!
__________________

Некропост, но всё же.

Выше были приведены два варианта для решения подобной задачи. Первый — на Паскале — у меня обозначен как version2. Второй — у Rififi — у меня обозначен как version1. Разница в количестве итераций циклов. В случае version1 цикл проработает столько раз, сколько значащих разрядов в двоичном представлении числа. В случае version2 цикл проработает ровно столько раз, сколько единиц в этом самом представлении. Вывод: version2 работает быстрее. На большом количестве тестов может сыграть роль.

Доказательство: на примере 1000 0000 (128 в двоичной).
1) version1 произведёт восемь итераций.
i — номер итерации, n — число.

i n
1 10000000
2 1000000
3 100000
4 10000
5 1000
6 100
7 10
8 1

2) version2 произведёт лишь одну итерацию.

10000000 & (10000000 — 1) == 10000000 & 1111111 == 0

Ну и код:

Подсчитать количество единиц в двоичном формате десятичного числа

Я пытаюсь узнать количество единиц в двоичной форме большого десятичного числа (десятичное число может достигать 1000000).

Я попробовал этот кусок кода:

Я хочу более быстрый алгоритм, так как он требует много времени для большого десятичного ввода. Пожалуйста, предложите мне эффективный алгоритм.

Решение

В C ++ вы можете просто сделать это.

Другие решения

То, что вы ищете, это «popcount», который реализован в виде одной инструкции CPU на более поздних процессорах x64, которые не будут побеждены по скорости:

Но, конечно, вам нужно сначала проверить, поддерживает ли он процессор:

Вот реализация в C:

Среда исполнения компилятора GNU C содержит «встроенный», который может быть быстрее, чем приведенная выше реализация (он может использовать команду popcnt ЦП, но это зависит от реализации):

Все вышеперечисленные реализации используются в моей шахматной библиотеке C ++, так как popcount играет жизненно важную роль в генерации шахматных ходов, когда используются битборды для представления позиций фигур. Я использую указатель функции, установленный во время инициализации библиотеки, чтобы указать на реализацию, запрошенную пользователем, а затем использую функцию popcount через этот указатель.

Google предоставит много других реализаций, так как это интересная проблема, например: http://wiki.cs.pdx.edu/forge/popcount.html .

Есть много способов. Легко понять и довольно быстро Путь Брайана Кернигана :

используя оператор сдвига вправо

Если вы примените операцию И к целому числу и результату вычитания, результатом будет новое число, которое совпадает с исходным целым числом, за исключением того, что крайний правый 1 теперь равен 0. Например, 01110000 И (01110000 — 1) = 01110000 И 01101111 = 01100000.

Это решение имеет время работы O (m), где m — это число 1 с в решении.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *