当前位置: 首页 > wzjs >正文

网站建设德语天津百度seo代理

网站建设德语,天津百度seo代理,网站建设优化服务平台,东莞建设网站推广公司地址位运算青铜挑战 位运算规则 位运算是直接对整数的二进制位进行操作的运算。在 Java 中&#xff0c;常用的位运算符有&#xff1a;&&#xff08;与&#xff09;、|&#xff08;或&#xff09;、^&#xff08;异或&#xff09;、~&#xff08;取反&#xff09;、<<&a…

位运算青铜挑战

位运算规则

位运算是直接对整数的二进制位进行操作的运算。在 Java 中,常用的位运算符有:&(与)、|(或)、^(异或)、~(取反)、<<(左移)、>>(算术右移)和>>>(逻辑右移)。

1. 按位与(&

  • 规则:只有两个相应的位都为1时,结果才为1,否则为0。
  • 示例
    int a = 5;  // 二进制:0101
    int b = 3;  // 二进制:0011
    int result = a & b;  // 结果:0001 (即1)
    System.out.println(result);  // 输出 1
    

2. 按位或(|

  • 规则:只要两个相应的位中有一个为1,结果就为1,否则为0。
  • 示例
int a = 5;  // 二进制:0101
int b = 3;  // 二进制:0011
int result = a | b;  // 结果:0111 (即7)
System.out.println(result);  // 输出 7

3. 按位异或(^

  • 规则:当两个相应的位相异(一个为0,另一个为1)时,结果为1;否则为0。
  • 示例
    int a = 5;  // 二进制:0101
    int b = 3;  // 二进制:0011
    int result = a ^ b;  // 结果:0110 (即6)
    System.out.println(result);  // 输出 6
    

      

4. 按位取反(~

  • 规则:反转二进制中的每一位,0变成1,1变成0。
  • 示例
    int a = 5;  // 二进制:0101
    int result = ~a;  // 结果:1010(对于32位系统,表示 -6)
    System.out.println(result);  // 输出 -6
    

5. 左移(<<

  • 规则:将所有的位向左移动指定的位数,右边用0填充。每左移一位,相当于乘以2。
  • 示例
    int a = 5;  // 二进制:0101
    int result = a << 1;  // 结果:1010 (即10)
    System.out.println(result);  // 输出 10
    

6. 算术右移(>>

  • 规则:将所有的位向右移动指定的位数,对于正数,左边补0,对于负数,左边补1(保留符号位)。
  • 示例
    int a = 5;  // 二进制:0101
    int result = a >> 1;  // 结果:0010 (即2)
    System.out.println(result);  // 输出 2int b = -5;  // 二进制:11111111111111111111111111111011
    int result2 = b >> 1;  // 结果:11111111111111111111111111111101 (即-3)
    System.out.println(result2);  // 输出 -3
    

7. 逻辑右移(>>>

  • 规则:将所有的位向右移动指定的位数,无论符号位如何,左边都补0。
  • 示例
    int a = -5;  // 二进制:11111111111111111111111111111011
    int result = a >>> 1;  // 结果:01111111111111111111111111111101 (即2147483645)
    System.out.println(result);  // 输出 2147483645
    
  • &|^ 运算符用于按位操作,针对两个整数的每一位。
  • ~ 运算符用于取反,将一个整数的每一位反转。
  • <<>>>>> 运算符用于位移操作,其中 << 是左移,>> 是算术右移,>>> 是逻辑右移。

位运算技巧

1. 判断一个数是否是2的幂

  • 原理:2的幂在二进制表示下只有一个1位,x & (x - 1) 的结果为0,表示x是2的幂。
  • 示例
    int x = 8;
    boolean isPowerOfTwo = (x & (x - 1)) == 0;
    System.out.println(isPowerOfTwo);  // 输出 true
    

2. 交换两个数

  • 原理:使用异或操作可以在不使用临时变量的情况下交换两个数。
  • 示例:
    int a = 5, b = 3;
    a = a ^ b;
    b = a ^ b;  // b = (a ^ b) ^ b = a
    a = a ^ b;  // a = (a ^ b) ^ a = b
    System.out.println("a: " + a + ", b: " + b);  // 输出 a: 3, b: 5
    

3. 提取二进制中最低的1位

  • 原理x & -x 可以提取二进制中最低的1位,常用于求解汉明重量二进制最右边的1的位置。
  • 示例
    int x = 12;  // 二进制:1100
    int lowestBit = x & -x;  // 结果:4 (二进制:0100)
    System.out.println(lowestBit);  // 输出 4
    

4. 清除最低的1位

  • 原理x & (x - 1) 会清除二进制中最低的1位。
  • 示例
    int x = 12;  // 二进制:1100
    x = x & (x - 1);  // 结果:8 (二进制:1000)
    System.out.println(x);  // 输出 8
    

5. 检测某一位是否为1

  • 原理(x & (1 << n)) != 0 可以检查x的第n位是否为1。
  • 示例
    int x = 5;  // 二进制:0101
    int n = 2;  // 检查第2位(从0开始数)
    boolean isBitSet = (x & (1 << n)) != 0;
    System.out.println(isBitSet);  // 输出 true,因为第2位是1
    

位运算白银挑战

位运算高频算法题

1 位移的妙用

1.1 位1的个数

编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为汉明重量)。详见leetcode191

public class HammingWeight {/*** 计算一个无符号整数的二进制表示中 '1' 的个数(汉明重量)。** @param n 无符号整数* @return 二进制表示中 '1' 的个数*/public int hammingWeight(int n) {int count = 0;// 循环直到 n 变为 0while (n != 0) {//  n & 1  等价于判断 n 的最低位是否为1。  //  如果是1,则count++count += (n & 1);// 无符号右移一位。  // 关键点:使用无符号右移(>>>)来确保最高位填充0,而不是符号位。// 这对于处理负数非常重要,因为Java中的整数是带符号的。n >>>= 1;  // 无符号右移一位,相当于除以2}return count;}public static void main(String[] args) {HammingWeight hw = new HammingWeight();// 示例用法int num1 = 11; // 二进制表示: 00000000000000000000000000001011int weight1 = hw.hammingWeight(num1);System.out.println("数字 " + num1 + " 的汉明重量是: " + weight1);  // 输出: 3int num2 = -3; // 二进制表示 (补码): 11111111111111111111111111111101  (32个1 - 2个1,所以2^32 - 3的二进制表示中1的个数)int weight2 = hw.hammingWeight(num2);System.out.println("数字 " + num2 + " 的汉明重量是: " + weight2);  // 输出: 31int num3 = 0;int weight3 = hw.hammingWeight(num3);System.out.println("数字 " + num3 + " 的汉明重量是: " + weight3); // 输出: 0}
}

1.2 比特位计数

给你一个整数 n ,对于 0 <= i <= n 中的每个 i ,计算其二进制表示中 1 的个数 ,返回一个长度为 n + 1 的数组 ans 作为答案。

public class CountingBits {/*** 计算 0 到 n (包含 n) 中每个数字的二进制表示中 '1' 的个数。** @param n 整数 n* @return 一个长度为 n + 1 的数组,包含每个数字的汉明重量。*/public int[] countBits(int n) {int[] ans = new int[n + 1];  // 创建一个数组来存储结果,大小为 n + 1for (int i = 0; i <= n; i++) {ans[i] = hammingWeight(i); // 对每个数字 i,计算其汉明重量并存储在数组中}return ans;}// 辅助函数:计算一个数的汉明重量 (和之前hammingWeight函数一样)private int hammingWeight(int n) {int count = 0;while (n != 0) {count += (n & 1);n >>>= 1;}return count;}// 更高效的动态规划方法public int[] countBitsDP(int n) {int[] ans = new int[n + 1];ans[0] = 0;  // 0 的汉明重量是 0for (int i = 1; i <= n; i++) {// i / 2  等价于 i >> 1 (右移一位)。  // i & 1 等价于 i % 2 (判断奇偶性)ans[i] = ans[i >> 1] + (i & 1);}return ans;}public static void main(String[] args) {CountingBits cb = new CountingBits();// 示例用法int n = 5;int[] result1 = cb.countBits(n);  // 使用基本方法System.out.print("数字 " + n + " 的 countBits 结果: ");for (int val : result1) {System.out.print(val + " ");}System.out.println(); // 输出: 0 1 1 2 1 2int[] result2 = cb.countBitsDP(n); // 使用动态规划方法System.out.print("数字 " + n + " 的 countBitsDP 结果: ");for (int val : result2) {System.out.print(val + " ");}System.out.println(); // 输出: 0 1 1 2 1 2}
}

1.3 颠倒无符号整数

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

public class ReverseBits {/*** 颠倒给定的 32 位无符号整数的二进制位。** @param n 要颠倒位的无符号整数* @return 位颠倒后的无符号整数*/public int reverseBits(int n) {int result = 0;// 遍历所有 32 位for (int i = 0; i < 32; i++) {// 1. 将 result 左移一位,为下一个最低有效位腾出空间result <<= 1;// 2. 获取 n 的最低有效位int bit = n & 1;// 3. 将 n 的最低有效位设置到 result 的最低有效位result |= bit;// 4. 将 n 右移一位,以便在下一次迭代中处理下一个位n >>>= 1;  // 使用无符号右移}return result;}// 优化后的方法,使用位运算和缓存private final int[] cache = new int[256]; // 缓存 8 位反转的结果public int reverseBitsOptimized(int n) {// 检查缓存是否已经初始化。只在第一次使用时初始化。if (cache[1] == 0) { // 假设 cache 未初始化时,cache[1] 为 0for (int i = 0; i < 256; i++) {cache[i] = reverseByte(i);}}// 将 32 位整数分解为 4 个 8 位字节,并使用缓存反转每个字节,然后组合结果return (cache[n & 0xff] << 24) |(cache[(n >>> 8) & 0xff] << 16) |(cache[(n >>> 16) & 0xff] << 8) |(cache[(n >>> 24) & 0xff]);}// 反转一个字节的位private int reverseByte(int b) {int result = 0;for (int i = 0; i < 8; i++) {result = (result << 1) | (b & 1);b >>>= 1;}return result;}public static void main(String[] args) {ReverseBits rb = new ReverseBits();// 示例用法int num = 43261596; // 00000010100101000001111010011100int reversedNum = rb.reverseBits(num);System.out.println("数字 " + num + " 的反转后的结果: " + reversedNum); // 输出: 964176192  (00111001011000010000101000000000)int optimizedReversedNum = rb.reverseBitsOptimized(num);System.out.println("数字 " + num + " 的优化反转后的结果: " + optimizedReversedNum); // 输出: 964176192}
}
public int reverseBits(int n) {int power = 31;int reversed = 0;while(power>=0){reversed += (n&1) << power;n = n >>> 1;power--;} return reversed;
}

2 通过位运算实现四则运算

2.1 两整数之和

给你两个整数 a 和 b ,不使用 运算符 + 和 - ,计算并返回两整数之和。详见leetcode371

public class SumWithoutPlus {/*** 不使用 + 和 - 运算符,计算两个整数的和。** @param a 第一个整数* @param b 第二个整数* @return 两个整数的和*/public int getSum(int a, int b) {// 使用位运算来模拟加法while (b != 0) {// 1. 计算进位 (carry): a & b//    & 运算符计算 a 和 b 中都为 1 的位。//    这些位需要产生进位。int carry = a & b;// 2. 计算没有进位的和 (sum): a ^ b//    ^ 运算符计算 a 和 b 中不同位的异或结果。//    这给出了没有考虑进位的和。a = a ^ b;// 3. 将进位左移一位,并将其分配给 b//    进位需要添加到下一位。//    左移一位等同于乘以 2,因为它将进位移动到下一位。b = carry << 1;}// 当进位为 0 时,a 包含最终的和return a;}public static void main(String[] args) {SumWithoutPlus swp = new SumWithoutPlus();// 示例用法int num1 = 1;int num2 = 2;int sum = swp.getSum(num1, num2);System.out.println(num1 + " + " + num2 + " = " + sum); // 输出: 1 + 2 = 3int num3 = -2;int num4 = 3;int sum2 = swp.getSum(num3, num4);System.out.println(num3 + " + " + num4 + " = " + sum2); // 输出: -2 + 3 = 1}
}

2.2 通过位运算实现乘法

递归乘法。 写一个递归函数,不使用 * 运算符, 实现两个正整数的相乘。可以使用加号、减号、位移,但要吝啬一些。详见leetcode08.05

public class RecursiveMultiply {/*** 使用递归方法,不使用 * 运算符,计算两个正整数的乘积。** @param a 第一个正整数* @param b 第二个正整数* @return 两个正整数的乘积*/public int recursiveMultiply(int a, int b) {// 确保 a 始终是较小的数字,以减少递归调用次数if (a > b) {return recursiveMultiply(b, a);}// 基本情况:如果 a 为 0,则乘积为 0if (a == 0) {return 0;}// 基本情况:如果 a 为 1,则乘积为 bif (a == 1) {return b;}// 递归步骤://   如果 a 是偶数:a * b = (a / 2) * 2 * b = (a / 2) * (b + b)//   如果 a 是奇数:a * b = (a - 1) * b + bif (a % 2 == 0) { // a 是偶数return recursiveMultiply(a / 2, b + b);  // 优化: b+b 可以替换为 b << 1} else { // a 是奇数return recursiveMultiply(a - 1, b) + b;}}// 更优化的版本,使用位运算public int recursiveMultiplyOptimized(int a, int b) {if (a > b) {return recursiveMultiplyOptimized(b, a);}if (a == 0) {return 0;}if (a == 1) {return b;}if ((a & 1) == 0) { // a 是偶数return recursiveMultiplyOptimized(a >> 1, b << 1);} else { // a 是奇数return recursiveMultiplyOptimized(a - 1, b) + b;}}public static void main(String[] args) {RecursiveMultiply rm = new RecursiveMultiply();// 示例用法int num1 = 3;int num2 = 5;int product = rm.recursiveMultiply(num1, num2);System.out.println(num1 + " * " + num2 + " = " + product); // 输出: 3 * 5 = 15int num3 = 7;int num4 = 8;int product2 = rm.recursiveMultiply(num3, num4);System.out.println(num3 + " * " + num4 + " = " + product2); // 输出: 7 * 8 = 56int num5 = 10;int num6 = 12;int product3 = rm.recursiveMultiplyOptimized(num5, num6);System.out.println(num5 + " * " + num6 + " = " + product3); // 输出: 10 * 12 = 120}
}

http://www.dtcms.com/wzjs/132302.html

相关文章:

  • 可视化导航网站源码国家职业技能培训官网
  • 网站 未备案 支付宝上海牛巨仁seo
  • b2c网站开发公司seo优化与品牌官网定制
  • jsp网站开发实例教学搜索引擎优化的工具
  • 美国外贸网站自媒体十大平台
  • wordpress广告最后加载百度推广优化师是什么
  • 网站设计需要什么专业如何搭建一个网站平台
  • 徐州个人建站模板国家免费技能培训有哪些
  • 福田企业网站建设网络营销的含义是什么
  • 南充商城网站建设宁德市疫情最新消息
  • 青海公司网站建设网络营销方式对比分析
  • 广州网站建设专注乐云seo移投界seo
  • 做电影网站详细教程流氓网站
  • 网站建设要注册哪些商标类别教育培训网
  • 免费网站建设浩森宇特家庭优化大师
  • 营口做网站价格百度公司在哪
  • 滨州教育平台 网站建设最佳搜索引擎磁力王
  • 江西学校网站建设百度问答平台入口
  • 王爷请自重沈阳seo排名外包
  • 网站设计公司电话网站建设推广专家服务
  • 太原做网站公司运营专注于网站营销服务
  • 公司网站建设gghhhj长沙关键词优化费用
  • 做商城网站系统近三年成功的营销案例
  • visual studio 2010 网站开发重庆seo网站建设
  • 江苏SEO网站建设网络营销成功的案例
  • 科技服务网站建设内容seo站长常用工具
  • 精品在线开发网站建设网络公司品牌推广
  • 做网站体会漯河seo推广
  • 渭南做网站的公司qq群推广引流免费网站
  • 建德 网站seo内容优化