C++中的位运算

本文介绍了C++中位运算的应用,包括计算二进制中1的个数、位运算实现加法、位运算交换两个数字以及利用位运算在数组中找到只出现一次的数字。通过位运算,可以在O(n)的时间复杂度和O(1)的空间复杂度下解决这些算法问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这里就稍微整理一下C++中典型的位运算算法。

题目1:(二进制中的1的个数)请实现一个函数,输入一个整数,输出该二级制表中1的个数。

int onesInNum(int num){
      int count=0;
      while(num){
           count++;
           num=(num-1)# //去掉一个1
      }
      return count;
}
相关题目:输入两个整数m和n。计算需要改变m的二进制表示中的多少位才能得到n。


题目2:位运算实现加法

int Add(int num1, int num2){
     int sum, carry;
     do{
          sum=num1^num2;  //加法非进位
          carry=(num1&num2)<<1; //加发进位
          num1=sum;   //继续循环
          num2=carry; 
     }while(num2);
     return num1;

}

题目3:利用位运算实现两个数字的交换

void swap(int& a, int& b){
       a=a^b; 
       b=a^b;  //a^b^b=a
       a=a^b;  //a^b^a=b
}

题目4:(数组中只出现一次的数组)一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度为O(n),空间复杂度为O(1)。

解析:不同与统计字符串中只出现一次的字符,这个没法用hash表实现,因为空间复杂度只能为Q(1)。所以这里得另辟蹊径。数字不同于字符另一个特征是可进行计算。这个题目比较特殊的地方在于其他数字都只出现两次。异或的一个性质:任何一个数字异或它自己等于0!

这里一种思路是先将数组中所有的数异或,这样得到那两个不同数字的异或值,其值肯定不为0,找到一个非0位,然后根据该位将数组分成两组,进行异或,最后得到的分别为那两个只出现一次的数字。

void findNumsAppearOnce(int *a, int len, int *num1, int *num2){
	if(a==NULL || len<=0) 
		return;
	
	int xo=0;
	for(int i=0;i<len;i++)
		xo=xo^a[i];
		
	unsigned flag=findFirstSetBit(xo);
	
	*num1=*num2=0; //这是设置0安全,不会对结果产生影响
	for(int i=0;i<len;i++){
		if(a[i]&(1<<flag))
			*num1^=a[i];
		else
			*num2^=a[i];	
	} 
} 

int findFirstSetBit(int num){
	int count=0;
	while((num&(1<<count))==0 && count<8*sizeof(int)){  //移动的位数不超过int类型的最大位数
		count++;	
	}
	return count;
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值