算法与数据结构1.1

文章介绍了利用位运算解决编程问题的几种方法,包括通过异或找出数组中重复的数字,计算二进制中1的个数,以及交换二进制位的奇偶数位。主要涉及位操作如与(&),异或(^),左移(<<)和右移(>>)在解决问题时的关键作用。
摘要由CSDN通过智能技术生成

1.之前知识复习

1).求二进制某位数是1or0,用其与&1or0,

 例如,1100100看齐从右向左第五位是0or1,就1100100&10000 结果为0,则为02

public class wei {

	public static void main(String[] args) {
		// TODO Auto-generated method stub

		System.out.println(100&16);
	}

}

 2).异或可以理解为不进位加法,参考半加器

3).若要交换两位数据a,b。即做三次异或,

int a=20;
int b=30;
//a=10100 b=11110
a=a^b;//a=01010
b=a^b;//b=10100
a=a^b;//a=11110

2.例题

 题目:1-1000放在含有1001个元素的数组中,只有唯一的一个元素值重复,其它均只出现一次.每个数组元素只能访问一次,设计一个算法,将它找出来;不用辅助存储空间,能否设计一个算法实现?

思想:本题的核心便是异或两个相同的数字为0,而随机的数字加数组内容和数组位置有三个,即得数字本身

public class wei {

	public static void main(String[] args) {
		int n=11;
		int[]a=new int[n];
		for(int i=0;i<n-1;i++) {
			a[i]=i+1;
		}
		a[a.length-1]=new Random().nextInt(1,n-1);//进行赋值
		
		int index=new Random().nextInt(1,n);//随机找到一个位置插入数组
		for(int i=0;i<n;i++) {
			System.out.print(a[i]);
		}
		//查看数组
		Until.swap(a,index,a.length-1);
		for(int i=0;i<n;i++) {
			System.out.print(a[i]);
		}
		System.out.println();
		int x=1;
		for(int i=0;i<n;i++) {
			x=x^a[i];
		}//异或数组内容1-10,还有随机的a【10】
//本题的核心便是异或两个相同的数字为0,而随机的数字加数组内容和数组位置有三个,即得数字本身
		for(int i=1;i<n-1;i++) {
			x=x^(i+1);
		}//异或位置1-10
		System.out.println(x);
		
	}

}

题目:任意输入一个数,求其二进制有几个一,例如:输入9(二进制为1001),则有两个“1”.

方法1

核心代码:

if ((n & (1 << i)) == (1 << i)) count++;

核心思想:将“1”进行位运算,并将其对输入数进行与运算。

int main() {
	int n = 0;
	scanf("%d", &n);
	//printf("")
	int count = 0;
	for (int i = 0; i < 32; i++) {
		if ((n & (1 << i)) == (1 << i)) //还可以将输入数反向方向位运算,进行与1的比较
			count++;
	}
	printf("%d", count);
}

方法2

核心思想;

x&(x-1)消除最小的一位“1”,如73(1001001)&72(1001000)为1001000 末位“1”,消去。

int main() {
	
	//方法二
	int n = 0;
	scanf("%d", &n);
	int count = 0;
	while (n != 0) {
		n = (n - 1) & n;
		count++;
	}
	printf("%d\n", count);
}

题目:交换二进制位的奇偶数位

核心思想:用二进制的0xaaaaaaaa和0x55555555进行数据保留和交换

int x = 9;
	int a = 0xaaaaaaaa;//10101010......1010 保留偶数位
	int b = 0x55555555;//0101......0101 保留奇数位

	int c = x & a;//10101010......1010 保留偶数位
	int d = x & b;//0101......0101 保留奇数位

	int e = (d << 1) ^ (c >> 1);//c只能向右走 若往左走则最头上的“1”保留的数据丢失

	printf("%d", e);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

懒羊羊和大耳朵图图

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值