位运算——二进制中1的数

位运算我们主要学了六种:按位与(&),按位或(|),按位异或(^),按位取反(~),左移(<<),按位右移(>>)。

我们先来看一道问题,求n在二进制上求第k个数字是几?

我们给一个万能的公式:n >> k &1

我们来解释一下:先看一个例子:将10转换为二进制

#include 
using namespace std;

int main()
{
	int n = 10;
	for (int k = 3; k >= 0; k--)
	{
		cout << (n >> k & 1);//输出1010
	}
	return 0;
}

我们都知道10的二进制对应为1010,那么我们来看一下上述是怎么算的呢?我们知道循环先进去,n >> 3,就是把10右移三位,是1,1再与1按位与,得1;然后n >> 2,把10右移两位,是10,10再与1(01)按位与,得1;然后 n >> 1 ,把10右移一位,得101,101与1(001)按位与的001,得1;最后 n >> 0,得1010,与1(0001)按位与得0,最后输出的结果就是1010。

总结: 公式 n >> k & 1,就是计算数字n在二进制下第k位数字是几。

以前,我们都写过这么个问题,就是在屏幕上输入数字,算出它对应的二进制数字

  1. 将数字除以%(模运算符)2,并将余数存储在数组中
  2. 通过/(除法运算符)将数字除以2
  3. 重复步骤2,直到数字大于零
#include 
using namespace std;

int main()
{
	int q[10], n, i;
	cin >> n;
	for (i = 0; n > 0; i++)
	{
		q[i] = n % 2;
		n /= 2;
	}
	for (i = i - 1; i >= 0; i--)
	{
		cout << q[i];
	}
	cout << endl;
	return 0;
}

我们再来看一个公式:求返回数字n在二进制中的最后一位1,: lowbit(n)= n & -n;

例如n = 1010,lowbit(n) = 10; n = 101000,lowbit(n )= 1000;

我们来讲一下为什么可以这样,我们必须要具备原码、反码、补码的知识,可以得到 x & (-x)= (~x + 1)

例如:

x = 1010…100…0
~x = 0101…011…1
~x+1 = 0101…100…0
x &(~x+1) = 0000…100…0

这样,我们就可以计算出数字n在二进制中的最后一位1;

示例:

题目要求:

给定一个长度为 n 的数列,请你求出数列中每个数的二进制表示中 1 的个数。

输入格式
第一行包含整数 n。

第二行包含 n 个整数,表示整个数列。

输出格式
共一行,包含 n 个整数,其中的第 i 个数表示数列中的第 i 个数的二进制表示中 1 的个数。

数据范围
1≤n≤100000,
0≤数列中元素的值≤10^9

输入样例:

5
1 2 3 4 5

输出样例:

1 1 2 1 2

#include 
using namespace std;

int lowbit(int x)
{
	return x & -x;
}

int main()
{
	int n;
	cin >> n;
	while (n--)
	{
		int x;
		cin >> x;

		int res = 0;
		while (x) x -= lowbit(x), res++;//每次减去x的最后一位1
		cout << res << ' ';
	}
	return 0;
}

你可能感兴趣的:(算法基础课,c++,算法,图论)