位运算解题-java

位运算解题

位运算,就是对数字进行左移右移与或非等各种操作,来实现解题

介绍常用的位运算操作

  1. 4>>1 4右移一位就是2 ,因为在计算机中都是以二进制运算位移也一样
  2. 4 << 1 4左移一位就是8 ,
  3. ~4 对4进行取反 是-5,因为计算机中是用补码进行运算比如4的原码是00000100,则补码就是00000100,对补码进行取反则 11111011,因为要用原码进行显示则就是补码变原码,正常负数的补码变原码都是取反+1,我这里有个技巧就是,从右往左数遇到第一个1则其1的左侧全部取反,第一个1保持不变,右侧不变,,10000101,-5;
  4. ^ 这个标志是异或,异或就是异或1则取反,异或0则保持不变,这里有个小技巧就是相同数字异或是0,于0异或就是本身,于全1异或就是按位全部取反
  5. & 与,你可以把它看成乘法,10 == 0,11 = 1。逻辑规则上是这样,这里介绍一个关于 &的小技巧,x代表一个10进制数 (x-1)&x 能消去最低位的1。如何判断这个数是否为2的幂次方可以用(x-1)&x==0
  6. | 或 , 你可以看作+法 1+1 == 1 ,1+0 ==1, 0+0 ==0。

现在就开始运用理论来实践

题目

题目1,找出唯一的成对的数

题目

在1-10这10个数放在含有11个元素的数组中,只有唯一的一个元素值重复,其它均只出现一次。,每个元素只能访问一次,不能使用辅助存储空间

解析

  1. 题目:规定了每个元素只能访问一次,并且不能使用辅助空间。
  2. 这篇文章是以位移为主题所以用位移来写,按照我们前面的常用运算符思路,能够解决这个题目。
  3. 该题目是从1-10中放到长度为11的数组中,因为是1-10数值,必然是1-10其中的一个重复值。

下面用图片解释

在这里插入图片描述
代码

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int a[] = {1,2,3,4,5,6,5,8,9,10,7};
		int b = 0;
		//下面这个功能就是拿1-10来异或数组中的1-10
		for (int i =1; i <=10; i++) {
			b= b^i;
		}
		for (int i = 0; i < a.length; i++) {
			b = b^a[i];
		}
		System.out.println(b);
	}

题目2: 二进制1的个数

题目

请实现一个函数,输入一个整数,输出该数的二进制表示中1的个数
例如:9的二进制表示为1001,有2位是1

解析

两个方法

  1. 一个用位移的方法 (x>>1)&1,来一位一位的判断
  2. 用(x-1)&x来找到最低位的1并且消掉

代码

//	第一种方法位移
	public static int weiyi(int n) {
		int sum = 0;
		while (n!=0) {
			if (((n>>0)&1)==1) {
				sum++;
			}
			n= n>>1;
		}
		return sum;
	}
	
// 第二个方法与方法
	public static int yu(int n) {
		int sum = 0;
		while (n != 0) {
			n= (n-1)&n;
			sum++;
		}
		return sum;
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner scanner = new Scanner(System.in);
		int n = scanner.nextInt();
		System.out.println("打印输入的数的二进制形式"+Integer.toString(n,2));
		System.out.println("位移的方法,1的个数为"+weiyi(n));
		System.out.println("与的方法,1的个数为"+yu(n));
	}

题目3:将整数的奇偶位置互换

题目

将整数的奇偶位置互换,假如有9这个数字1001,互换后是0110;变成6了

解析

  1. 先把原数字和010101010101进行与运算把所有的偶数位置给剥离出来
  2. 在把原数字和1010101010进行与运算把所有的奇数位置给剥离出来
  3. 偶数位置左移一位变成奇数上的值
  4. 奇数位置右移一位变成偶数上的值
  5. 把算出来的两个值异或一下就是奇偶位置互换的值了

在这里插入图片描述
代码
自行完善,int型是32位

我这里暂时不写,过段时间有空更新在评论区

题目3:出现k次与出现一次

题目

数组中有这样一个数出现1次,其他的数都出现了k次,请输出只出现一次的数

解析

有这样一个规律 相同二进制进行2次按位不进位加法是等于0,相同10进制进行10次按位不进位加法是等于0
相同n进制进行n次按位的不进位加法是等于0

代码

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int a[] = {2,2,8,2,7,3,7,3,7,3,10,10,10,100,100,100,0,0,0,12139999,12139999,12139999};
		int k =3;
		char[][] aStrings = new char[a.length][];
		int maxlen =0;
		for (int  i =0;i<a.length; i++) {
			aStrings[i] = Integer.toString(a[i],k).toCharArray();
			if (aStrings[i].length>maxlen) {
				maxlen  = aStrings[i].length;
			}
		}
		int[] b = new int[a.length]; // 用来存入运算结果按位来加
		for (int i = 0; i <a.length; i++) {
			for (int j= aStrings[i].length-1;j>=0;j--) {
				b[j] += aStrings[i][j] - '0'; 
				if (b[j] >= k) {  //如果大于等于k说明要进位了则进行不进位加法,把进位去掉也就-k
					b[j] -= k;
				}
			}
		}
		int ans=0;
		for (int i = 0; i < b.length; i++) {
			ans += b[i]*Math.pow(k, i); // 把k进制转换成10进制
		}
		System.out.println(ans);
	}

文章内容来源和参考于 蓝桥学院《算法真美课程》郑未老师。
学好算法,走遍天下都不怕,仅此激励自己不断学习
描述有问题的,评论或者私聊我,我继续改成完善。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值