Рассмотрим следующую проблему из книги (https://cses.fi/book/book.pdf): "Сначала рассмотрим задачу генерации всех подмножеств набора из n элементов. Например, подмножествами {0,1,2} являются φ,{0}, {1}, {2}, {0,1}, {0,2}, {1,2} и {0,1,2}. Существует два распространенных метода генерации подмножеств: мы можемвыполнить рекурсивный поиск или использовать битовое представление целых чисел. "
Решение № 2 в книге (стр. 48, PDF, стр. 58) следующее:
for (int b = 0; b < (1<<n); b++) {
vector<int> subset;
for (int i = 0; i < n; i++) {
if (b&(1<<i)) subset.push_back(i);
}
}
Мой вопрос:почему работает сравнение (b&(1<<i))
? Что это делает в фоновом режиме? Я пробовал это вручную для подмножеств {0, 1}, и это работает безупречно, но только почему сравнения между ними работают?b
является счетчиком количества элементов, а (1<<i)
, насколько я понимаю, в основном эквивалентно 2 i . Почему все это работает? Это похоже на магию.
PS. Я знаю, что книга - плохой справочник по C ++, я читаю ее больше для объяснений алгоритма.