На стр. 140 of Programming Pearls, 2nd Edition, Джон предложил реализацию наборов с битовыми векторами.
Теперь мы перейдем к двум окончательным структурам, которые используют тот факт, что наши множества представляют целые числа. Бит-векторы - старый друг из колонки 1. Вот их личные данные и функции:
enum { BITSPERWORD = 32, SHIFT = 5, MASK = 0x1F };
int n, hi, *x;
void set(int i) { x[i>>SHIFT] |= (1<<(i & MASK)); }
void clr(int i) { x[i>>SHIFT] &= ~(1<<(i & MASK)); }
int test(int i) { return x[i>>SHIFT] &= (1<<(i & MASK)); }
Как я понял, центральная идея битового вектора для представления целочисленного набора, как описано в столбце 1, состоит в том, что i-й бит включается тогда и только тогда, когда целое число я находится в наборе.
Но я действительно в недоумении по алгоритмам, участвующим в вышеупомянутых трех функциях. И книга не дает объяснений.
Я могу получить только то, что i & MASK
должен получить младшие 5 бит i, а i>>SHIFT
- переместить я 5 бит вправо.
Кто-нибудь будет более подробно описывать эти алгоритмы? Бит-операции всегда кажутся мифом для меня: (