网易游戏笔试题:输入一个数n,返回一个数组,数组中每个元素对应[0,n]每个数的二进制中1的个数

该博客介绍了如何输入一个正数n,计算从0到n每个数二进制表示中1的个数。提供了解决问题的算法,包括用位操作求一个数的二进制中1的个数,判断一个数是否为2的幂,以及计算N!中质因数2的个数的方法。示例中n=5,返回数组A=[0,1,1,2,1,2]。" 112895737,10538565,Graphpad Prism绘制折线图和柱状图教程,"['图形绘制工具', '数据分析', '科研绘图', '统计图表']

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

题目:

输入一个数n(保证输入正数),返回一个数组,数组中每个元素对应[0,n]每个数的二进制中1的个数

如:n=5,返回A=[0,1,1,2,1,2]

给出的函数声明int* BitCountArr(int n,int *sizeArr);

#include<iostream>

using namespace std;

int* BitCountArr1(int n,int *sizeArr)//方法一
{
	sizeArr = new int[n + 1];	
	int j = 0;
	for (int i = 0; i <= n; i++)
	{
		int count = 0;
		int k = i;
		while (k > 0)//常规思想:每次和1按位与,是1计数器值+1,然后将数右移一位
		{
			if (1 == (k&1))
				count++;
			k = k>> 1;
		}
		sizeArr[j++] = count;
	}	
	return sizeArr;
}

int* BitCountArr2(int n, int *sizeArr)//方法二
{
	sizeArr = new int[n + 1];
	int j = 0;
	for (int i = 0; i <= n; i++)
	{
		int k = i;
		int count = 0;
		while (k != 0)//第二种思想:每次与k-1按位与,清除最低位的1: 1111→1110→1100→1000→0000 所以是四个1 ;1000→0000 所以是1个1
		{
			k &= (k - 1);
			count++;
		}
		sizeArr[j++] = count;
	}
	return sizeArr;
}

int main()
{
	int n = 5;
	int *sizeArr1 = new int[6];
	for (int i = 0; i < 6; i++)
		sizeArr1[i] = 0;
	sizeArr1 = BitCountArr1(5, sizeArr1);//调用函数数时会拷贝另一个指针为sizeArr1,
					//所以要用一个指针sizeArr1接收函数返回的指针,而不能直调用 BitCountArr1(5, sizeArr1)后打印sizeArr1

	for (int i = 0; i <= 5; i++)
		cout << sizeArr1[i] << " ";
	cout << endl;
	delete[] sizeArr1;
	int *p=NULL;//指针在使用时必须初始化,即使是初始化为NULL
	int *sizeArr2=BitCountArr2(5, p);
	for (int i = 0; i <= 5; i++)
		cout << sizeArr2[i] << " ";
	delete[] sizeArr2;
	system("pause");
	return 0;
}

总结:n&(n-1)的用处

1.求数的二进制形式中1的个数

int count=0;

while(n != 0)

{

n = n&(n-1);

count++;

}

2.判断一个数是否是2的幂

if(n > 0 && ( 0 == n&(n-1)))

return true;

3.计算N!的质因数2的个数

假设是8! 有1 2 3 4 5 6 7 8

第一次 则它有 2 4 6 8四个具有2的质因数

第二次 2 4 6 8变为 1 2 3 4 则只有 2 4具有2的质因数

第三次 2 4 变为 1 2 则只有2 具有2的质因数 

公式 f(n) = (n/2) + (n/4) + (n/8) + (n/16) + ...  

推及一般N!的质因数2的个数为N - (N二进制表示中1的个数)

8!:8-1=7个

int count=0;

while(n != 0)

{

n = n&(n-1);

count++;

}

int sum2=N-count;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值