У мене криється підозра, що ти отримав цей код із тієї самої книги, яку я читаю ... Сам код тут не настільки виразний, як оператори- | =, & та <<, які зазвичай не використовуються нам непростого - автор не потрудився займати додатковий час у поясненні процесу, а також, що насправді тут стосуються механіки. Спочатку я був задоволений попередньою відповіддю на цю тему, але лише на абстрактному рівні. Я повернувся до цього, бо відчув, що потрібно конкретніше пояснення - відсутність одного завжди залишає у мене неприємне почуття.
Цей оператор << - лівий побітний зсув, він приймає двійкове представлення цього числа або операнда і переміщує його, однак безліч місць, визначених операндом чи числом праворуч, як у десяткових числах лише у двійкових колах. Ми множимо на базу 2 - коли ми рухаємось вгору, однак багато місць, які не базуються 10, тому число праворуч є показником, а число ліворуч - базовим кратним 2.
Цей оператор | = візьміть операнда зліва і / або його з операндом праворуч, а цей - '&' і є бітами обох операндів зліва та справа від нього.
Отже, у нас є хеш-таблиця, яка зберігається у 32-бітовому двійковому номері кожного разу, коли шашка отримує or'd ( checker |= (1 << val)
) з позначеним бінарним значенням букви, відповідним бітом якого він встановлюється в true. Значення символу є і з контролем ( checker & (1 << val)) > 0
) - якщо воно більше 0, ми знаємо, що у нас є dupe - тому що два однакових біта встановлені на 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'
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
Тепер він оголошує дублікат