网易游戏笔试题:输入一个数n,返回一个数组,数组中每个元素对应[0,n]每个数的二进制中1的个数
2016-04-17 17:04
260 查看
题目:
输入一个数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;
输入一个数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;
相关文章推荐
- WebSocket(4)-- WebSocket与TCP、Http的关系
- 回文串---吉哥系列故事——完美队形II
- js中时间问题
- 获取java中src目录的方法
- Spring学习笔记(四)-- Spring事务全面分析
- 专业版V9.1SP1提示"运行时错误,-2147417848(80010108)
- android仿qq聊天界面的的布局适配器的写法
- POJ3176-Cow Bowling
- WebSocket(2)--为什么引入WebSocket协议
- WebSocket(3)-- WebSocket协议简介
- linux中的帮助命令
- 构建之法阅读笔记03
- python显示系统信息脚本
- HDU 4411 Arrest 费用流
- virual box快速安装max系统
- Five-People:常用控件及其属性(RadioButton,CheckBox,align,margin,padding)使用方法
- 静态类型与动态类型
- 依赖注入、控制反转
- BCGControlBar使用方法
- asp.net控件库FineUI使用入门图解