其实这篇文章可以挖的很深,从二进制的本质出发有很多可以考虑的点。但是我并不能理解这么深55555
从题目中的问题出发,我们将十进制转换为二进制的时候使用的是什么方法呢?
将该数跟2取余,再除于2,反复操作,所有的余数加起来就是目标二进制数。那么统计其中位是1的位只需要在模2的时候记录累加。在将原来的数除以2.代码如下:
#include <iostream>
using namespace std;
// 通过对数取模运算,余一的就是二进制位为一,将这些统计起来
// 其实这么想的思路就是计算二进制的方法,我们计算二进制的方法不过是把十进制的数字通过对2取余,余数即是二进制数
int bitNumber (int number) {
int ret = 0;
while (number != 0) {
if (number % 2 == 1)
ret++;
number /= 2;
}
return ret;
}
// 上述方法只可以检测正数,最负数无可奈何
int main ()
{
int number;
cin >> number;
cout << "Way one is : " << bitNumber (number) << endl;
cout << "Way two is : " << bitNumber1(number) << endl;
cout << "Way three is : " << bitNumber2 (number) << endl;
return 0;
}
上述代码可以基本实现功能,但是如果这个数特别大,时间复杂度就会很高。如果这个数是负数这个方法也不可以使用。
所以为了解决第一个问题我们可以对取余进行改进,将取余改成和1做与运算,除法改成向右进位,其实就是对运算符的改进,不是很好。
#include <iostream>
using namespace std;
// 通过对数取模运算,余一的就是二进制位为一,将这些统计起来
// 其实这么想的思路就是计算二进制的方法,我们计算二进制的方法不过是把十进制的数字通过对2取余,余数即是二进制数
int bitNumber (int number) {
int ret = 0;
while (number != 0) {
if (number % 2 == 1)
ret++;
number /= 2;
}
return ret;
}
// 上述方法只可以检测正数,最负数无可奈何
// 和第一种解法思路差不多,我们一位一位的统计是不是1
// 先判断该数二进制的最后一位是不是1,再将该数向右移动一位
// 判断的方法是通过对数的最后一位进行与运算(只有两个数都是1才是1)
// 让当前数和1进行与运算,1的除最后一位外都是0,所以只会对最后一位检测
int bitNumber1 (int number) {
int ret = 0;
while (number != 0) {
if (number & 1 == 1)
ret++;
number = number >> 1;
}
return ret;
}
// 上述方法虽然效率高,但是也不能检测负数
int main ()
{
int number;
cin >> number;
cout << "Way one is : " << bitNumber (number) << endl;
cout << "Way two is : " << bitNumber1(number) << endl;
cout << "Way three is : " << bitNumber2 (number) << endl;
return 0;
}
但是这种方法虽然效率上有一点点的改进,不过还是没有解决不能计算负数的问题
所以我们一直对该数和该数减一做与运算,这样知道结果为0就是全部1的个数:
#include <iostream>
using namespace std;
// 通过对数取模运算,余一的就是二进制位为一,将这些统计起来
// 其实这么想的思路就是计算二进制的方法,我们计算二进制的方法不过是把十进制的数字通过对2取余,余数即是二进制数
int bitNumber (int number) {
int ret = 0;
while (number != 0) {
if (number % 2 == 1)
ret++;
number /= 2;
}
return ret;
}
// 上述方法只可以检测正数,最负数无可奈何
// 和第一种解法思路差不多,我们一位一位的统计是不是1
// 先判断该数二进制的最后一位是不是1,再将该数向右移动一位
// 判断的方法是通过对数的最后一位进行与运算(只有两个数都是1才是1)
// 让当前数和1进行与运算,1的除最后一位外都是0,所以只会对最后一位检测
int bitNumber1 (int number) {
int ret = 0;
while (number != 0) {
if (number & 1 == 1)
ret++;
number = number >> 1;
}
return ret;
}
// 上述方法虽然效率高,但是也不能检测负数
// 没看懂的方法,写写看
int bitNumber2 (int number) {
int ret = 0;
while (number != 0) {
number = number & (number - 1);
ret++;
}
return ret;
}
int main ()
{
int number;
cin >> number;
//cout << "Way one is : " << bitNumber (number) << endl;
//cout << "Way two is : " << bitNumber1(number) << endl;
cout << "Way three is : " << bitNumber2 (number) << endl;
return 0;
}
各种原因是什么我还要在考虑一下