У меня есть подозрение, что вы получили этот код из той же книги, которую я читаю ... Сам код здесь не настолько загадочный, как операторы- | =, &, <<, которые обычно не используются мы, неспециалист, - автор не удосужился потратить дополнительное время на объяснение процесса и на то, какова действительная механика, которая здесь задействована. Я был доволен предыдущим ответом на эту тему в начале, но только на абстрактном уровне. Я вернулся к этому, потому что чувствовал, что нужно более конкретное объяснение - его отсутствие всегда вызывает у меня неприятное чувство.
Этот оператор << является левым побитовым сдвигом, он принимает двоичное представление этого числа или операнда и сдвигает его на любое количество мест, указанных операндом или числом справа, как в десятичных числах только в двоичных файлах. Мы умножаем на основание 2 - когда мы двигаемся вверх, но во многих местах не основание 10 - так что число справа - это показатель степени, а число слева - это основание, кратное 2.
Этот оператор | = берет операнд слева и / или его с операндом справа - и этот - '&' и биты обоих операндов слева и справа от него.
Итак, у нас есть хеш-таблица, которая хранится в 32-битном двоичном числе каждый раз, когда проверяющий получает or'd ( checker |= (1 << val)
) с заданным двоичным значением буквы, соответствующий его бит, для которого устанавливается значение true. Значение символа равно and'd с помощью checker ( checker & (1 << val)) > 0
) - если оно больше 0, мы знаем, что у нас есть дублирование, - потому что два идентичных бита, установленные в true и имеющие вместе, вернут true или '1' '.
Есть 26 двоичных разрядов, каждое из которых соответствует строчной букве - автор сказал, что строка содержит только строчные буквы - и это потому, что у нас осталось только 6 (в 32-битном целом) месте для использования - и чем мы столкнуться
00000000000000000000000000000001 a 2^0
00000000000000000000000000000010 b 2^1
00000000000000000000000000000100 c 2^2
00000000000000000000000000001000 d 2^3
00000000000000000000000000010000 e 2^4
00000000000000000000000000100000 f 2^5
00000000000000000000000001000000 g 2^6
00000000000000000000000010000000 h 2^7
00000000000000000000000100000000 i 2^8
00000000000000000000001000000000 j 2^9
00000000000000000000010000000000 k 2^10
00000000000000000000100000000000 l 2^11
00000000000000000001000000000000 m 2^12
00000000000000000010000000000000 n 2^13
00000000000000000100000000000000 o 2^14
00000000000000001000000000000000 p 2^15
00000000000000010000000000000000 q 2^16
00000000000000100000000000000000 r 2^17
00000000000001000000000000000000 s 2^18
00000000000010000000000000000000 t 2^19
00000000000100000000000000000000 u 2^20
00000000001000000000000000000000 v 2^21
00000000010000000000000000000000 w 2^22
00000000100000000000000000000000 x 2^23
00000001000000000000000000000000 y 2^24
00000010000000000000000000000000 z 2^25
Итак, для входной строки 'azya', по мере продвижения по шагам
строка «а»
a =00000000000000000000000000000001
checker=00000000000000000000000000000000
checker='a' or checker;
// checker now becomes = 00000000000000000000000000000001
checker=00000000000000000000000000000001
a and checker=0 no dupes condition
строка 'az'
checker=00000000000000000000000000000001
z =00000010000000000000000000000000
z and checker=0 no dupes
checker=z or checker;
// checker now becomes 00000010000000000000000000000001
строка 'azy'
checker= 00000010000000000000000000000001
y = 00000001000000000000000000000000
checker and y=0 no dupes condition
checker= checker or y;
// checker now becomes = 00000011000000000000000000000001
Строка 'Azya'
checker= 00000011000000000000000000000001
a = 00000000000000000000000000000001
a and checker=1 we have a dupe
Теперь он объявляет дубликат