二进制字符串余数3

时间:2013-11-14 13:13:10

标签: algorithm bit-manipulation modular-arithmetic

- 当x是二进制数时,如何找到x mod 3?不允许使用转换为十进制,然后使用%operator。

-eg-如果x为1101则输出应为1但不要将1101转换为13然后按%3查找

6 个答案:

答案 0 :(得分:2)

既然你说“字符串”,我将添加以下技巧:

请注意,如果您在二进制数的末尾附加0,则将其值加倍。如果您在末尾附加1,则将其加倍并添加1。

也就是说,如果您处理了所有数字到一定数字(将此数字称为该数字a),并且您知道a % 3 = x某些x=1, 2 or 0,那么你可以告诉我们:

a0 % 3 = (2 * a) % 3 = (2 % 3) * (a % 3) % a = (2 * (a % 3)) % 3
a1 % 3 = (2 * a + 1) % 3 = (2 % 3) * (a % 3) + (1 % a) % a = (2 * (a % 3) + 1) % 3

这样,您可以轻松做出以下区分:

Current mod | Next digit | New mod
------------+------------+---------
   0            0            0
   0            1            1
   1            0            2
   1            1            0
   2            0            1
   2            1            2

也就是说,您可以从左到右遍历字符串(假设为msbf表示法)并根据表更新new mod。您从current mod = 0开始。

答案 1 :(得分:0)

A%B相当于A - (floor(A / B)* B)。如果您可以使用二进制数执行减法,乘法和整数除法,则可以模拟%运算符而不实际使用它。

答案 2 :(得分:0)

它非常快速和创新。

二进制中的3是11,即基数为11中的11。因此我们知道一个数字可以被11整除,如果奇数位数的总和与偶数位数的数字之和的差值为0或可整除到了11.

所以添加偶数1s并添加奇数1。与众不同。请检查以下程序,我们正在做同样的事情。如果你有相同的字符串也适用。

public static boolean isDivisible(int n){
    if(n<0){
        n=-n;
    }
    if(n==0)return true;
    if(n==1)return false;
    int even=0, odd=0;
    while(n!=0){
        if((n&1)==1){
            odd++;
        }
        n=n>>1;
        if(n==0)break;
        if((n&1)==1){
            even++;
        }
    }
    return isDivisible(even-odd);
}

有关详情,您可以关注thisthis

答案 3 :(得分:0)

要判断十进制数是否可以在基数10中被9整除,只需将其数字加在一起并重复直到只有一位数。如果该数字为0,3,6或9,则它可以被9整除。

这基于相同的原理,但对于基数4中可被3整除的数字:

int mod3 (int x) {
  if (x<0) x = -x;
  while (x & 0x7fff0000) x = ((x & 0x7fff0000)>>16) + (x & 0x0000ffff);
  while (x & 0xff00) x = ((x & 0xff00)>>8) + (x & 0x00ff);
  while (x & 0xf0) x = ((x & 0xf0)>>4) + (x & 0x0f);
  while (x & 0x0c) x = ((x & 0x0c)>>2) + (x & 0x03);
  while (x>=3) x -= 3;
  return x;
}

答案 4 :(得分:0)

如果您注意到2^N mod 3 = 2 if N is odd & 2^N mod 3 = 1 if N is even(它可以通过归纳证明),而且二进制no是2的幂的总和,所以只检查1是否出现在奇数或偶数幂的字符串中并执行值的运行总和。模块化算术中有定理

(a+b+c)%m = ((a)%m + (b)%m + (c)%m )%m

例如。

x = 1101有2个偶数幂2(2 ^ 0,2 ^ 2)和1个奇数幂2(2 ^ 3)

因此res =(2 * 1 + 2)mod 3 = 4 mod 3 = 1

Java实现: -

public class Modulus {

    public static int modulo3(String s) {

        int end = s.length()-1;
        int sum = 0;
        for(int i =0;i<s.length();i++) {

           if(s.charAt(end)=='1') {
               if(i%2==0)
                   sum = sum + 1;
               else sum = sum + 2;
           } 

           end--; 
        }
       return(sum%3); 
    }


    public static void main(String[] args) {

        System.out.println(modulo3("1110"));
    }

}

答案 5 :(得分:0)

这里的概念是,如果你在任何二进制数字的末尾添加0或1,那么数字将加倍加上0或1基于下一位设置和否,提醒也将变为[previous_reminder * 2 +(0或1) ]。 并在此步骤后计算提醒:提醒=提醒%3;

这是java代码:

public static void main(String[] args) {
    int[] arr = { 1, 1, 0, 1, 1, 0, 0, 1, 1, 1};
    // Assumed first bit is always set therefore reminder will be 1.
    int reminder = 1;

    for (int i = 1; i < arr.length; i++) {
        reminder = reminder * 2 + arr[i];
        reminder = reminder % 3;
    }
    System.out.println(reminder);
}