📜  检查二进制流中的可除性

📅  最后修改于: 2021-05-25 01:13:30             🧑  作者: Mango

二进制数流即将来临,任务是判断到目前为止形成的数是否可被给定数n整除。
在任何给定时间,您将得到0或1,并判断由这些位形成的数字是否可被n整除。

通常,电子商务公司会问这类问题。在Microsoft采访中有人问我。实际上,这个问题有点简单,面试官将n固定为3。

方法1(简单,但会导致溢出):

继续计算形成的数字,然后仅检查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 \n";
    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 \n";
        else
            std::cout << "no \n";
    }
}

该解决方案中的问题:溢出怎么办。由于0和1将继续出现,并且形成的数字将超出整数范围。

方法2(不会引起溢出):

在此解决方案中,我们仅需保持余数为0,则形成的数字可被n整除,否则不能被n整除。这与自动机中用来记住状态的技术相同。在这里,我们还记得输入数字可分的状态。

为了实现此技术,我们需要观察二进制数的值在附加0或1后如何变化。

让我们举个例子。假设您有二进制数字1。
如果将其附加0,它将变为10(十进制2),意味着前一个值的2倍。
如果加上1,它将变为11(十进制为3),是先前值+1的2倍。

它如何帮助获得剩余物?
可以以m = an + r的形式写任何数字(n),其中a,n和r是整数,r是余数。因此,当m乘以任何数字时,余数就是。假设m乘以x,则m为mx = xan + xr。所以(mx)%n =(xan)%n +(xr)%n = 0 +(xr)%n =(xr)%n;

我们只需要对余数进行上述计算(当数字被附加0或1时计算数值)。

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 
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 \n";
    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 \n";
        else
            cout << "no \n";
    }
}
  
// Driver code
int main()
{
    CheckDivisibility(3);
    return 0;
}

输入:

1
0
1
0
1
-1

输出:

Press any key other than 0 and 1 to terminate 
no 
no 
no 
no 
yes 

相关文章:
基于DFA的部门
检查流是否为3的倍数