Algorithmic clearance village - bit operation

1. Common bit operations

1.1 with &

&: The bits corresponding to both numbers are 1, then the result is 1
1 & 1 = 1
1 & 0 = 0;
0 & 0 = 0;

1.2 or |

|: As long as there is a 1 in the corresponding bit of the two numbers, the result is 1
1 | 1 = 1;
1 | 0 = 1;
0 | 0 = 0;

1.3 XOR^

^: Return 0 only when the digits of the two numbers are the same, otherwise return 1
1 ^ 1 = 0
0 ^ 1 = 1
0 ^ 0 = 0;

1.4 Trade-off ~

~: It is the inversion, if the bit is 1, the inversion is 0
~1=0
~0=1

2. Shift operations

Left shift: << All binary numbers are shifted to the left by a certain number of bits (if one bit is left, it is divided by 2)
Right shift: >> All binary numbers are shifted to the right by a certain number of bits

3. The number of bit 1

Number of 1's
Write a function that takes as input an unsigned integer (as a binary string) and returns the number of '1' digits in its binary representation (also known as the Hamming weight).

3.1 Shift right

You only need to perform an AND operation on each bit and 1. If the current bit is 1, then count i=0
00000000000000000000000000001011 & …1=1
i=1 00000000000000000000000000000101 & …1=1
i=2 000000000000 000000000000000000010 & ... 1=0
i =3 00000000000000000000000000000001 & …1=1

The result is 3

 public int hammingWeight(int n) {
    
    
        int count =0;
        for(int i=0;i<32;i++){
    
    
            count+=(n>>i)&1;
        }
        return count;
    }

3.2 Shift left

先设置一个mask之用于左移比较是否位相同
00000000000000000000000000001011 & 1 =0
00000000000000000000000000001011 & 01 = 0
00000000000000000000000000001011 & 001 =0

00000000000000000000000000001011 & 00000000000000000000000000001 = 1
00000000000000000000000000001011 & 000000000000000000000000000001 = 0
00000000000000000000000000001011 & 0000000000000000000000000000001 = 1
00000000000000000000000000001011 & 00000000000000000000000000000001 = 1

 public int hammingWeight(int n) {
    
    
       int count =0;
       int mask = 1;
       for(int i=0;i<32;i++){
    
    
           if((n & mask) !=0){
    
    
               count++;
           }
           mask<<=1;
       }
       return count;
    }

3.3 n&(n-1)

Change the last 1 in binary to 0 until n finally becomes 0
0000000000000000000000000001011 & 000000000000000000000000001010 = 00000000000000000000000000001010
count = 1;

00000000000000000000000000001010 & 00000000000000000000000000001001 = 00000000000000000000000000001000
count = 2;

00000000000000000000000000001000 & 00000000000000000000000000000111 =
0000000000000000000000000000000
count =3;

 public int hammingWeight(int n) {
    
    
        int count =0;
       while(n!=0){
    
    
           n=n&(n-1);
           count++;
       }
       return count;
    }

This kind of efficiency is also relatively high, often used, the first two displacements need to traverse 32 times, and n&(n-1) only needs to exit when n is 0
insert image description here

4. Bit counting

Bit counting
Given you an integer n, for each i in 0 <= i <= n, count the number of 1s in its binary representation, and return an array ans of length n + 1 as the answer.
Input: n = 2
Output: [0,1,1]
Explanation:
0 --> 0
1 --> 1
2 --> 10

4.1 Shift right

The calculation of the number of 1s here can use the previous ( n>>i ) &1, where n is the current value, and i is the number of bits shifted to the right. Obviously, because the element size is in the range of 0-
n Therefore, the current value can be known according to the corresponding subscript, then compare with &1 again, and then move to the right to calculate the number of 1, and then assign it to the array.

    public int[] countBits(int n) {
    
    
        int [] res = new int [n+1];
        for(int i=0;i<=n;i++){
    
    
            for(int j=0;j<32;j++){
    
    
                res[i] += (i >>j)&1;
            }
        }
        return res;
    }

The disadvantage of this method is that it takes a long time, because each element has to be traversed and moved to the right 32 times to calculate the number of 1s

4.2 Properties of bits n&(n-1)

public int[] countBits(int n) {
    
    
        int count =0;
        int [] res = new int [n+1];
        for(int i=0;i<=n;i++){
    
    
            res[i] = getOneCount(i);
        }
        return res;
    }

    public int getOneCount(int x){
    
    
        int count =0;
        while(x!=0){
    
    
            x=x&(x-1);
            count++;
        }
        return count;
    }

5. Reverse the bits

颠倒给定的 32 位无符号整数的二进制位。

提示:

请注意,在某些语言(如 Java)中,没有无符号整数类型。在这种情况下,输入和输出都将被指定为有符号整数类型,并且不应影响您的实现,因为无论整数是有符号的还是无符号的,其内部的二进制表示形式都是相同的。
在 Java 中,编译器使用二进制补码记法来表示有符号整数。因此,在 示例 2 中,输入表示有符号整数 -3,输出表示有符号整数 -1073741825

5.1 Bitwise inversion

At first, I thought about reversing the binary number directly. It is definitely not possible to directly use the reverse of Integer.
First get the last digit of n, then n is logically shifted to the right, and added to the reversed reversed number until n becomes 0 00000010100101000001111010011100 and the lowest bit is 0 n logically shifted to the right by 1 bit 00000001010010100000111101001110
to
the
right 30 bits, the lowest bit is 0

 public int reverseBits(int n) {
    
    
        int reversed =0;
        int length = 31;
        while(n!=0){
    
    
            reversed += (n&1)<<length;
            // 逻辑右移
            n >>>= 1;
            length--;
        }
        return reversed;
    }

6. Sum of two integers

Sum of Two Integers
Given you two integers a and b, without using operators + and -​​​​​​​​, calculate and return the sum of two integers.
Input: a = 2, b = 3
Output: 5

6.1 XOR+AND

2: 010
3: 011
5: 101
It can be seen that the same is 0, and the difference is 1. This is XOR. For the part that does not need to carry, use a^b, but you need to pay attention to whether the first digit is 0 or 1, and the carry part must be used a&b, carry is only required when both are 1.

public int getSum(int a, int b) {
    
    
        while(b!=0){
    
    
            int sign = (a & b) << 1;
            a = a ^ b;
            b = sign;
        }
        return a;
    }

a&b= 010 010 << 1 = 100 sign = 100
a^b= 001 a = 001
b = 100

a&b = 100 & 001 = 000 000<1 =000 sign =0
a^b = 100 ^ 001 = 101 a = 101
b =0
free

a=101 =5

7. Recursive multiplication

Recursive multiplication
Recursive multiplication. Write a recursive function to multiply two positive integers without using the * operator. Plus, minus, shifts are fine, but be stingy.
Input: A = 3, B = 4
Output: 12

7.1 Bit operations

For example, 3 * 4 is 3 * 2 ^ 2, which is 3<<2, shifted two places to the left.
For example, 1 * 10 is 1 (2+8) is 1 * 2^1+1 2 ^3 is 1 << 1 +1<<3

First find the minimum and maximum values ​​between the two. The reason for choosing the minimum value as the multiplier is that the number of times is small, and then judge whether the rightmost bit of min is 1. If it is 1, add this bit to the result, and then Move the minimum value one place to the right

 public int multiply(int A, int B) {
    
    
       int add = 0;
       int min = Math.min(A,B);
       int max = Math.max(A,B);
       for(int i=0;min!=0;i++){
    
    
           if((min & 1) == 1){
    
    
               add  += max<< i;
           }
           min >>= 1;
       }
       return add;
    }

For example 1 * 10 min = 1, max = 10, min &1 =1, add = 10 << 0 = 1010=10
min >>1 = 0 exit

例如 3* 4 min = 3 max =4 min & 1= 1 add = 4 << 0 =4
min >> 1 = 01 min & 1= 1 add = 4 + 4 << 1 = 4 + 8 = 12

Guess you like

Origin blog.csdn.net/qq_52843958/article/details/132343264