位运算

在 Java 中,位运算是对二进制数据进行操作的运算符。

Java 中包括以下位运算符:

(1)逻辑位运算符

  1. 按位与(&) :二进制位按位相与,对应位置上的两个位都为1时结果为1,否则为0。
1
2
(n & 1) //得到n的最后一位  
//只有当n的最后一位也是1时,其结果才为1
1
2
3
4
5
6
7
8
9
10
11
//计算某二进制数的1的个数
public int oneCount(int n){
int count = 0;
while(n > 0){
count += n & 1;
n >>= 1;
}
return count;
}
//相当于
count = Integer.bitCount(n);
  1. 按位或(|) :二进制位按位相或,都为0时结果为0,否则为1。
        有一位为 1 结果就为1
        val = (val << 1) | root.val;
  2. 按位异或(^) :二进制位按位相异或,相同为0,不同为1。
        异或运算 有以下三个性质:
        ①任何数和 0 做异或运算,结果仍然是原来的数,即 a^0=a
        ②任何数和其自身做异或运算,结果是 0,即 a^a=0
        ③异或运算满足交换律和结合律,即 a^b^a = b
         a^b^a
        =b^a^a
        =b^(a^a)
        =b^0
        =b
        异或运算的规则是,如果两个操作数的对应位相同,则结果为 0;如果两个操作数的对应位不同,则结果为 1。
        int a = 5; // 二进制表示为 0101
        int b = 3; // 二进制表示为 0011
        int result = a ^ b; // 二进制表示为 0110,十进制表示为 6
  3. 按位取反(~) :将二进制位取反,0变为1,1变为0。

(2)位移运算符

  1. 左移(<<) :将二进制数向左移动指定位数,低位补0,相当于乘以2的指定次方。
        1<<left:表示将二进制数 1 左移 left 位。
        例如,假设 left = 3,则 1<<left 将会把二进制数 1 左移 3 位后得到 1000,二进制数 1000 转为十进制就是 8

    通常情况下,使用左移运算符 << 可以快速地实现将原始数据所代表的位数扩大 2 的幂次方倍

  1. 右移(>>) :将二进制数向右移动指定位数,高位补符号位,正数补0,负数补1,相当于除以2的指定次方。
  2. 无符号右移(>>>) :将二进制数向右移动指定位数,高位补0,相当于无符号除以2的指定次方

实际使用中,位运算主要用于二进制数据的处理和优化,比如位移运算可以用来对2的次幂进行快速计算,按位与运算可以用来对数据进行掩码处理等等。但要注意的是,在使用位运算时需要特别小心,因为位运算会改变数据类型和位数,可能导致数据溢出或类型转换错误。

以下是一些位运算的示例:

1
2
3
4
5
6
7
8
9
10
int a = 0b1010; // 定义二进制数10
int b = 0b1100; // 定义二进制数12

int c = a & b; // 二进制位相与,结果为 0b1000,即10
int d = a | b; // 二进制位相或,结果为 0b1110,即14
int e = a ^ b; // 二进制位相异或,结果为 0b0110,即6
int f = ~a; // 二进制位取反,结果为 0b0101,即-11(注意Java中的补码表示方式)
int g = a << 2; // 将二进制数向左移动2位,结果为 0b101000,即40
int h = a >> 1; // 将二进制数向右移动1位,结果为 0b0101,即5
int i = b >>> 2;// 将二进制数向右移动2位,结果为 0b0011,即3

应用

tmp |= 1 << (c[i]-‘a’)
用一个整数表示字符集合

在代码中,通过 tmp |= 1 << (c[i]-'a') 的操作,实际上是在一个整数 tmp 中的不同比特位上设置为 1,每个字符对应整数的不同比特位。这样做的目的是为了将字符集合转换为一个整数,方便进行比较和处理。

举个例子,假设字符集合为 {‘a’, ‘b’, ‘c’},则对应的整数表示为:

  • ‘a’ 对应整数的第 0 位,即 000…0001
  • ‘b’ 对应整数的第 1 位,即 000…0010
  • ‘c’ 对应整数的第 2 位,即 000…0100

将这些整数按位或操作后,得到的整数就能表示字符集合 {‘a’, ‘b’, ‘c’},可以方便地比较不同字符串的字符集合是否相似。

1
2
3
4
5
6
7
int num = words[i].charAt(j) - 'a';
//用1标记出现的字母
binary |= (1 << num);


//无重复位
(temp[i] & temp[j]) == 0

在这段代码中,使用(1 << c)而不是(1 << (c-'a'))的原因是为了简化代码并提高效率。

  1. 简化代码:使用(1 << c)可以直接将字符c对应的比特位置为1,不需要额外的计算c-'a'来确定字符在字母表中的位置。这样可以减少代码的复杂度和提高可读性。
  2. 提高效率:在计算机中,位运算比加减法操作更快速和高效。因此,直接使用(1 << c)来设置比特位可以更快地更新特征值,而不需要进行字符位置的减法运算。

综上所述,使用(1 << c)来更新特征值可以简化代码并提高效率,是一种更好的选择。

Donate
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.

扫一扫,分享到微信

微信分享二维码
  • Copyrights © 2023-2025 Annie
  • Visitors: | Views:

嘿嘿 请我吃小蛋糕吧~

支付宝
微信