Проверить делимость в двоичном потоке
Идет поток двоичного числа, задача - сказать, что образовавшееся число делится на заданное число n.
В любой момент вы получите 0 или 1 и узнаете, делится ли число, образованное этими битами, на n или нет.
Обычно такие вопросы задают компании электронной коммерции. Об этом меня спрашивали в интервью Microsoft. На самом деле этот вопрос был немного простым, интервьюер установил n равным 3.
Keep on calculating the number formed and just check divisibility by n.
/* Simple implementation of the logic, without error handling compiled with Microsoft visual studio 2015 */ void CheckDivisibility2( int n) { int num = 0; std::cout << "press any key other than" " 0 and 1 to terminate
" ; while ( true ) { int incomingBit; // read next incoming bit via standard // input. 0, 00, 000.. are same as int 0 // ans 1, 01, 001, 00..001 is same as 1. std::cin >> incomingBit; // Update value of num formed so far if (incomingBit == 1) num = (num * 2 + 1); else if (incomingBit == 0) num = (num * 2); else break ; if (num % n == 0) std::cout << "yes
" ; else std::cout << "no
" ; } } |
Проблема в этом решении: А как насчет переполнения. Поскольку 0 и 1 будут продолжать поступать, а образованное число выйдет за пределы целого диапазона.
В этом решении мы просто сохраняем остаток, если остаток равен 0, в противном случае сформированное число делится на n. Это тот же метод, который используется в автоматах для запоминания состояния. Здесь мы также запоминаем состояние делимости входного числа.
Чтобы реализовать эту технику, нам нужно наблюдать, как изменяется значение двоичного числа, когда к нему добавляются 0 или 1.
Возьмем пример. Предположим, у вас есть двоичное число 1.
Если к нему добавлен 0, он станет 10 (2 в десятичной системе), что означает, что в 2 раза больше предыдущего значения.
Если к нему добавить 1, оно станет 11 (3 в десятичной системе), что в 2 раза превышает предыдущее значение +1.
Как это помогает получить остаток?
Любое число (n) можно записать в виде m = an + r, где a, n и r - целые числа, а r - остаток. Итак, когда m умножается на любое число, получается остаток. Предположим, что m умножено на x, поэтому m будет mx = xan + xr. поэтому (mx)% n = (xan)% n + (xr)% n = 0 + (xr)% n = (xr)% n;
We need to just do the above calculation (calculation of value of number when it is appended by 0 or 1 ) only over remainder.
When a binary number is appended by 0 (means multiplied by 2), the new remainder can be calculated based on current remainder only. r = 2*r % n; And when a binary number is appended by 1. r = (2*r + 1) % n;
// C++ program to check divisibility in a stream #include <iostream> using namespace std; /* A very simple implementation of the logic, without error handling. just to demonstrate the above theory. This simple version not restricting user from typing 000, 00 , 000.. , because this all will be same as 0 for integer same is true for 1, 01, 001, 000...001 is same as 1, so ignore this type of error handling while reading just see the main logic is correct. */ void CheckDivisibility( int n) { int remainder = 0; std::cout << "press any key other than 0" " and 1 to terminate
" ; while ( true ) { // Read next incoming bit via standard // input. 0, 00, 000.. are same as int 0 // ans 1, 01, 001, 00..001 is same as 1. int incomingBit; cin >> incomingBit; // Update remainder if (incomingBit == 1) remainder = (remainder * 2 + 1) % n; else if (incomingBit == 0) remainder = (remainder * 2) % n; else break ; // If remainder is 0. if (remainder % n == 0) cout << "yes
" ; else cout << "no
" ; } } // Driver code int main() { CheckDivisibility(3); return 0; } |
Вход:
1 0 1 0 1 -1
Выход:
Нажмите любую клавишу, кроме 0 и 1, чтобы завершить нет нет нет нет да
Статьи по Теме:
Подразделение на основе DFA
Убедитесь, что поток кратен 3
Эта статья предоставлена Puneet . Если вам нравится GeeksforGeeks, и вы хотели бы внести свой вклад, вы также можете написать статью на сайте deposit.geeksforgeeks.org или отправить свою статью по электронной почте: grant@geeksforgeeks.org. Посмотрите, как ваша статья появляется на главной странице GeeksforGeeks, и помогите другим гикам.
Пожалуйста, напишите комментарии, если вы обнаружите что-то неправильное, или вы хотите поделиться дополнительной информацией по теме, обсужденной выше
Вниманию читателя! Не прекращайте учиться сейчас. Освойте все важные концепции DSA с помощью самостоятельного курса DSA по приемлемой для студентов цене и будьте готовы к работе в отрасли. Чтобы завершить подготовку от изучения языка к DS Algo и многому другому, см. Полный курс подготовки к собеседованию .
Если вы хотите посещать живые занятия с отраслевыми экспертами, пожалуйста, обращайтесь к Geeks Classes Live и Geeks Classes Live USA.