Я хочу реализовать двоичный счетчик на C++, используя std::bitset
. Если я явно разработаю функцию сложения для bitset
, то сложность алгоритма возрастет до O (n ^ 2). Есть ли способ сделать это O (n)?
Также есть ли хорошие описания решения проблемы суммы подмножеств Горовица и Сахни? Кроме Википедии, я не смог найти ни одного хорошего источника, описывающего их алгоритм.
Реализация двоичного счетчика с использованием std::bitset
Ответы (2)
На ваш второй вопрос: «Есть ли хорошие описания решения проблемы суммы подмножеств Горовица и Сахни?» Я нашел несколько статей:
Оригинал статьи Горовица и Сахни:
http://www.cise.ufl.edu/~sahni/papers/computingPartitions.pdf
Обсуждение Stackoverflow об улучшениях алгоритма Горовица и Сахни:
Сгенерировать все суммы подмножеств в диапазоне быстрее, чем O((k+N) * 2^(N/2))?
Исходный код:
http://www.diku.dk/hjemmesider/ansatte/pisinger/subsum.c
Если набор битов достаточно мал, чтобы все биты могли поместиться в unsigned long
, то вы можете использовать его функции преобразования для выполнения над ним целочисленной арифметики, например
bitset = std::bitset(bitset.to_ulong() + 1);
В C++11 также есть функция to_ullong()
, дающая unsigned long long
, которая может быть больше, чем unsigned long
.
Если ваши наборы битов слишком велики для этого, вам может быть лучше реализовать свои собственные, основанные на массиве или векторе целых чисел, к которым может получить доступ ваш счетчик. Ваш алгоритм по-прежнему будет O(n2), но вы можете уменьшить количество операций, необходимых для каждого добавления, по сравнению с обработкой одного бита за раз.