| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 6992 人关注过本帖, 1 人收藏
标题:如何用位运算比较二进制数中1和0的个数
只看楼主 加入收藏
墨清扬
Rank: 8Rank: 8
等 级:蝙蝠侠
威 望:1
帖 子:294
专家分:817
注 册:2011-10-4
结帖率:100%
收藏(1)
已结贴  问题点数:20 回复次数:17 
如何用位运算比较二进制数中1和0的个数
遇到一道题,要确定的一个数的二进制表示中1多还是0多,见识了位运算的神奇之后就纠结这道题能不能用位运算……
搜索更多相关主题的帖子: 神奇 二进制 如何 
2012-04-15 19:07
beyondyf
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:103
帖 子:3282
专家分:12654
注 册:2008-1-21
收藏
得分:5 
能。下面给一段不计算前导0的代码。带前导0的计算有更有趣的算法

//cal返回值为数中1与0的数量差
int cal(unsigned int a)
{
    int c;
    if(a == 0) return -1;
    for(b0 = b1 = 0; a; a >>= 1)
        if(a & 1) c++; else c--;
    return c;
}

重剑无锋,大巧不工
2012-04-15 19:18
墨清扬
Rank: 8Rank: 8
等 级:蝙蝠侠
威 望:1
帖 子:294
专家分:817
注 册:2011-10-4
收藏
得分:0 
回复 2楼 beyondyf
呃……不是这个意思……要更快更神奇的,最好只能由位运算实现的,比如这个算法可以用别的方法实现

酱油实习生
2012-04-15 20:24
czz5242199
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:小飞侠
威 望:4
帖 子:660
专家分:2400
注 册:2011-10-26
收藏
得分:8 
如果输入n为一个32位整数,这段代码是求n的2进制中1有多少个
程序代码:
#include <stdio.h>

int n;

int main()
{
    scanf("%d",&n);
    n=(n & 0x55555555)+((n>>1) & 0x55555555);
    n=(n & 0x33333333)+((n>>2) & 0x33333333);
    n=(n & 0x0F0F0F0F)+((n>>4) & 0x0F0F0F0F);
    n=(n & 0x00FF00FF)+((n>>8) & 0x00FF00FF);
    n=(n & 0x0000FFFF)+((n>>16) & 0x0000FFFF);
    printf("%d\n",n);
    
    system("pause");
}
2012-04-15 20:44
墨清扬
Rank: 8Rank: 8
等 级:蝙蝠侠
威 望:1
帖 子:294
专家分:817
注 册:2011-10-4
收藏
得分:0 
回复 4楼 czz5242199
能稍微解释一下吗?授人以鱼不如授人以渔~

酱油实习生
2012-04-15 20:53
czz5242199
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:小飞侠
威 望:4
帖 子:660
专家分:2400
注 册:2011-10-26
收藏
得分:0 
首先把32位分成16份,每份两个数,我们先求出每相邻两个数一共有多少个1,如此对于每一份,左边1个数是n&010101...01,右边是(n>>1) & 0101..01

如此一次后,这16份每份存的都是原数中1的个数

之后16份变8份,8份变4份,直到变成1份
2012-04-15 20:59
Wikyo_hoho
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:31
专家分:188
注 册:2012-3-12
收藏
得分:0 
楼上只是判断1的个数,可是要判断一个数1多还是0多,还需要知道这个数占多少位啊。
2012-04-15 21:03
墨清扬
Rank: 8Rank: 8
等 级:蝙蝠侠
威 望:1
帖 子:294
专家分:817
注 册:2011-10-4
收藏
得分:0 
回复 6楼 czz5242199
大概……有点明白了……再消化消化……

酱油实习生
2012-04-15 21:16
beyondyf
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:103
帖 子:3282
专家分:12654
注 册:2008-1-21
收藏
得分:0 
回复 4楼 czz5242199
有意思的做法,又一次思维的开拓

重剑无锋,大巧不工
2012-04-15 21:43
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
回复 楼主 墨清扬
图片附件: 游客没有浏览图片的权限,请 登录注册


程序代码:
#include <cstdio>
#include <conio.h>

void main(void)
{
    while (true)
    {
        int value(0);
        printf_s("请输入整数(以0终结):");
        if (scanf_s("%d", &value) > 0)
        {
            printf_s("\n输入: %d ", value);
            if (value == 0)
            {
                break;
            }
            printf_s("二进制: ");
            bool begin(false);
            unsigned int n(0x80000000);
            size_t count1(0);
            size_t count2(0);
            for (size_t i = 0; i < sizeof(int) * 8; ++i)
            {
                int ch((value & n) == n ? '1' : '0');
                if (!begin && (ch == '1'))
                {
                    begin = true;
                }
                if (begin)
                {
                    putchar(ch);
                    (ch == '1') ? ++count1 : ++count2;
                }
                n >>= 1;
            }
            printf_s(" 共%d个'1' %d个'0'", count1, count2);
            putchar('\n');
        }
        else
        {
            printf_s("\n非法数据!");
            break;
        }
    }
    printf_s("\n按任意键结束...");
    _getch();
}


[ 本帖最后由 TonyDeng 于 2012-4-16 02:46 编辑 ]

授人以渔,不授人以鱼。
2012-04-16 02:38
快速回复:如何用位运算比较二进制数中1和0的个数
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.048437 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved