[剑指Offer]12.二进制中1的个数

题目

输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。

思路

把一个整数减去1,再和原整数做与运算,会把整数最右边一个1变成0.那么一个整数的二进制表示中有多少个1,就可以进行多次这样的操作。

代码

/*---------------------------------------
*   日期:2015-07-20
*   作者:SJF0115
*   题目: 12.二进制中1的个数
*   结果:AC
*   网址:http://www.nowcoder.com/books/coding-interviews/8ee967e43c2c4ec193b040ea7fbb10b8?rp=1
*   来源:剑指Offer
*   博客:
-----------------------------------------*/
#include <iostream>
#include <vector>
#include <string>
#include <stack>
#include <algorithm>
using namespace std;

class Solution {
public:
    int NumberOf1(int n){
        int count = 0;
        while(n){
            n &= (n-1);
            ++count;
        }//while
        return count;
    }
};

int main(){
    Solution s;
    int n;
    while(cin>>n){
        int result = s.NumberOf1(n);
        // 输出
        cout<<result<<endl;
    }//while
    return 0;
}

思路二

我们可能很快就有一个思路:先判断整数二进制表示中最右边一位是不是1.接着把输入的整数右移一位,此时原来处于从右边数起第二位被移到最右边了,再判断是不是1。这样每次移动一位,直到整个整数变成0为止。基于这个思路我们写完下面的程序。但是当我们输入一个负数时,这个方法就会出现问题。比如0x80000000,把负数0x80000000右移一位时并不是简单的把最高位的1移到第二位变成0x40000000,而是0xC0000000。这是因为移位前是个负数,仍然要保证移位后是个负数,因此移位后最高位仍然是1。如果一直做右移运算,最终这个数字就会变成0xFFFFFFFF而陷入死循环

代码二

class Solution {
public:
    int NumberOf1(int n){
        int count = 0;
        while(n){
            if(n & 1){
                ++count;
            }//if
            n = n >> 1;
        }//while
        return count;
    }
};

思路三

为了避免死循环,我们可以不右移输入的数字n。首先把n和1做与运算,判断n的最低位是不是为1。接着把1左移一位得到2,再和n做与运算,就能判断n的次低位是不是1…….这样反复左移,每次都能判断n的其中一位是不是1。

代码三

/*---------------------------------------
*   日期:2015-07-20
*   作者:SJF0115
*   题目: 12.二进制中1的个数
*   结果:AC
*   网址:http://www.nowcoder.com/books/coding-interviews/8ee967e43c2c4ec193b040ea7fbb10b8?rp=1
*   来源:剑指Offer
*   博客:
-----------------------------------------*/
#include <iostream>
#include <vector>
#include <string>
#include <stack>
#include <algorithm>
using namespace std;

class Solution {
public:
    int NumberOf1(int n){
        int count = 0;
        int base = 1;
        while(base){
            if(n & base){
                ++count;
            }//if
            base = base << 1;
        }//while
        return count;
    }
};

int main(){
    Solution s;
    int n;
    while(cin>>n){
        int result = s.NumberOf1(n);
        // 输出
        cout<<result<<endl;
    }//while
    return 0;
}
时间: 2024-08-24 13:46:52

[剑指Offer]12.二进制中1的个数的相关文章

剑指Offer之二进制中1的个数

题目描述: 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 输入: 输入可能包含多个测试样例. 对于每个输入文件,第一行输入一个整数T,代表测试样例的数量.对于每个测试样例输入为一个整数. .n保证是int范围内的一个整数. 输出: 对应每个测试案例, 输出一个整数,代表输入的那个数中1的个数. 样例输入: 3 4 5 -1 样例输出: 1 2 32 [解析]: /********************************* * 日期:2013-11-18 * 作者:SJ

二进制中1的个数_java

前言 最近会手写一些常考的面试题目,测试通过后会跟大家分享一下 移位法仅适应于正数的做法: 移位法就是每次判断n的二进制的最低位是否为1,时间复杂度为O(logn) 复制代码 代码如下: int nativeOnenum(int n)   {       int count = 0;       while (n) {           if (n & 1)  count ++;           n >>= 1;       }       return count;   } 对

位运算求解一个整数的二进制中1的个数

法一: #include<iostream> #include<algorithm> using namespace std; int Count(int x){ int ans = 0; while(x != 0){ ++ans; x = x&(x-1); } return ans; } int main(){ cout<<Count(9999)<<endl; return 0; } 输出结果:8 分析如下: 1. Count函数用来计算某个数x的

[剑指Offer]5.二维数组中的查找

题目 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 思路 [算法系列之三十三]杨氏矩阵 代码 /*--------------------------------------- * 日期:2015-07-19 * 作者:SJF0115 * 题目: 5.二维数组中的查找 * 网址:http://www.nowcoder.com/books/coding-interviews/a

剑指offer系列之十:二进制中1的个数

题目描述: 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示.比如输入9,9的二进制表示是1001,1的个数是2,所以输出2. 这有一个重要结论:一个数与该数减一的结果进行与运算,会把该数右边(低位)第一个1变为0,而该位左边保持不变(高位).可以举一个简单的例子进行证明:比如1100(对应十进制是12),减去1之后的结果是1011(也就是十进制的11),两个数进行与运算之后,我们发现最后的结果是1000(对应十进制的8,当然这个8与后面没有关系,可以略过).这样我们每进行一次的与

《剑指offer》-二叉搜索树与双向链表

输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树中结点指针的指向. 题目的描述不是很习惯.题目的意思是把二叉树从左到右遍历,相当于双向链表的遍历. 其实就是让二叉树在x方向上的投影点,顺序输出.那么其实就是中序遍历.递归版本如下: struct TreeNode{ int val; struct TreeNode* left; struct TreeNode* right; TreeNode(int x) : val(x), left(NULL),

JavaScript 特有方法计算二进制中1的个数 split方法_javascript技巧

代码如下: 复制代码 代码如下: function g(n){ var n = n.toString(2); var count = 0; for(var i=0;i<n.length;i++) { if(n[i] == "1") count++; } return count; } 觉得这样写很麻烦,突然想到是不是可以利用js的split方法来实现计算1的个数,split的参数为正则\0*\,分离字符串中的1.代码如下: 复制代码 代码如下: function f(n){ re

[剑指Offer] 第2章课后题详解

[剑指Offer] 第2章课后题详解 目录 剑指Offer 第2章课后题详解 目录 有序数组的插入 分析 正常解法 非主流解法 两个队列实现栈 分析 解法 2的整数次方 分析 解法 不同位数 分析 解法 有序数组的插入 本题为<剑指Offer>"面试题4:替换空格"一节中的"相关题目". 有两个排序的数组A1和A2,内存在A1的末尾有足够多的空余空间容纳A2.请实现一个函数,把A2中的所有数字插入到A1中并且所有数字是排序的. 分析 其实这道题就是实现一

剑指offer系列之三:在二维数组中查找元素

题目描述: 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 由于题目条件的成立,所以使得这道题可以使用对角线的方法完成,可以从右上角的元素考虑,如果目标查找元素小于右上角的元素,那么不可能在右上角元素所在的列,如果目标大于剩余列的右上角的元素,那么不可能在该右上角元素所在的行.依照这个规律,就可以完成目标元素的查找(参考剑指offer书中的思路).基于此,我写出如下的代码(已被