栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

颠倒二进制位(字符串,位操作,分治 Java)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

颠倒二进制位(字符串,位操作,分治 Java)

问题

给你一个int,把他的二进制完全倒换过来,然后再输入int

问题参考:190. 颠倒二进制位

方案

1. 字符串操作:很容易想到,操作字符串跟直观

2. 字符数组操作,都可以使用位操作来替代,比如获取哪一位(& 0000 0010), 将结果累加上 (0 | 0010 ),或者增量(0000 0010 << 1, 就可以获取第三位)

3. 读取原始int值二进制最后一位,挨个放在result结果的最高位

4. 读取原始int值二进制最后一位,挨个放在result的最后一位,放之前全部享有移动一个位

5. 字符串跌倒还有种分支算法,即前后字符串跌倒。类似二进制也可以。

1.字符串操作

其中用到技术点

1. 交互char数值,可以参考:位运算.异或概念,性质,应用(交换数值,序列只有一个数重复,序列只有一个不重复)_要钱也要自我实现-CSDN博客

2. 获取int类型的二进制字符串:Integer.toBinaryString(n) 

3. 将二进制转换为int:(int) Long.parseLong(binary,2)。其中Integer.valueOf("10111111111111111111111111111111",2)首字母为1的会解析报错,就使用了long解析函数

		
		public int reverseBits1(int n) {

			String binary = String.format("%32s", Integer.toBinaryString(n)).replaceAll(" ", "0");
			char[] chars = binary.toCharArray();

			for(int i = 0,j=chars.length-1 ;i 
 2.位操作:始终读取int最后一位,从高位到低位挨个放 

将二进制按照字符串存储,很浪费内存。

截取最后一位,然后移动到对应位置,跟result(init=0)或

图示

 

 代码
		
		public int reverseBits2(int n) {
			// 结果变量 每次出来的二进制位“拼接”进去
			int result = 0;
			// int的二进制位数
			int len = 31; 
			// 中间变量存储
			int temp = 0;
			while(len >= 0 && n != 0){
				// 获取最后一位
				temp = n & 1;
				// 向左移动
				temp = temp << (len--);
				// 拼接到结果上
				result = result | temp;
				// 去掉最后一位
				n = n >>> 1;
			}
			return result;
		}
3.位操作变种:始终读取int最后一位,每次放在第一位 图示

 代码
		
		public int reverseBits3(int n) {
			// 结果变量 每次出来的二进制位“拼接”进去
			int result = 0;
			// int的二进制位数
			int len = 31; 
			// 中间变量存储
			int temp = 0;
			while(len >= 0){
				// 获取最后一位
				temp = n & 1;
				// 向左移动一位
				result = result << 1;
				// 拼接到结果最后一位上
				result = result | temp;
				// 去掉最后一位
				n = n >>> 1;
				// 递减
				len --;
			}
			return result;
		}
4.分治+位操作

- 对比第二种和第三种 遍历次数基本是32次
- 改善:一位一位操作太麻烦,能否一次操作几个二进制位。
加上分治算法思想,AB字符串反过来就是BA,如果A或者B也是字符串,前后颠倒就行,好在这里32是2的4次方,固定的,不需要迭代,可以直接写死。

图示

 代码

1. 如果是字符串这么搞,是从:前16和后16位换,前16的前8位和16的后8位换,以此类推;
2. 二进制也可以这么搞,但会出现很多中间变量
3. 优化结果是:从下往上,奇偶互换,两位两位互换,四位四位互换,…… ,前16位和后边16位互换

		public int reverseBits(int n) {

			final int M1 = 0x55555555; // 01010101010101010101010101010101
			final int M2 = 0x33333333; // 00110011001100110011001100110011
			final int M4 = 0x0f0f0f0f; // 00001111000011110000111100001111
			final int M8 = 0x00ff00ff; // 00000000111111110000000011111111
			final int M16 = 0x0000ffff; // 00000000000000001111111111111111

			
			n = n >>> 1 & M1 | (n & M1) << 1;
			
			
			
			n = n >>> 2 & M2 | (n & M2) << 2;
			n = n >>> 4 & M4 | (n & M4) << 4;
			n = n >>> 8 & M8 | (n & M8) << 8;
			
			return n >>> 16 & M16 | (n & M16) << 16;
		}
总结

1. 对int的二进制操作,逻辑上可以转为二进制char[]处理的,都可以按照位操作实现

2. 对int的二进制操作,优先考虑位操作。相对于char[]的操作,位操作更简单,比如:前16和后16互换n = n >>> 16 | n << 16

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/750776.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号