苦苦寻找一个位的算法

affss 2009-12-04 01:42:41
有两个相关的问题:

1,一个定长的字符串,假设是10字节,求它有几位为 1 ,最快的算法是什么?


2,两个int整数,求它有几位同时为 1 ,最快的算法是什么?我把两个数 & 了一下,可是只得到另一个数,并不能得到想要的结果。



...全文
190 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
affss 2009-12-15
  • 打赏
  • 举报
回复
对的呀,本来就是3呀 32+16+8=56
likee003 2009-12-05
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 litaoye 的回复:]
帮LZ搜索了1个log(n)的,效率比较稳定,比那个n&(n-1)平均效率好一些,
另外改一改int64也适用,这样的话,6次就可以算8个256的,也不错了!

int count_bits(unsigned long n)
{
    //0xAAAAAAAA,0x55555555分别是以“1位”为单位提取奇偶位
    n = ((n & 0xAAAAAAAA) >> 1) + (n & 0x55555555);

    //0xCCCCCCCC,0x33333333分别是以“2位”为单位提取奇偶位
    n = ((n & 0xCCCCCCCC) >> 2) + (n & 0x33333333);

    //0xF0F0F0F0,0x0F0F0F0F分别是以“4位”为单位提取奇偶位
    n = ((n & 0xF0F0F0F0) >> 4) + (n & 0x0F0F0F0F);

    //0xFF00FF00,0x00FF00FF分别是以“8位”为单位提取奇偶位
    n = ((n & 0xFF00FF00) >> 8) + (n & 0x00FF00FF);

    //0xFFFF0000,0x0000FFFF分别是以“16位”为单位提取奇偶位
    n = ((n & 0xFFFF0000) >> 16) + (n & 0x0000FFFF);

    return n;
}
[/Quote]

我编了个试验程序,证明不对。
#include <iostream>
#include <iomanip>
using namespace std;

int count_bits(unsigned long n)
{
//0xAAAAAAAA,0x55555555分别是以“1位”为单位提取奇偶位
n = ((n & 0xAAAAAAAA) >> 1) + (n & 0x55555555);

//0xCCCCCCCC,0x33333333分别是以“2位”为单位提取奇偶位
n = ((n & 0xCCCCCCCC) >> 2) + (n & 0x33333333);

//0xF0F0F0F0,0x0F0F0F0F分别是以“4位”为单位提取奇偶位
n = ((n & 0xF0F0F0F0) >> 4) + (n & 0x0F0F0F0F);

//0xFF00FF00,0x00FF00FF分别是以“8位”为单位提取奇偶位
n = ((n & 0xFF00FF00) >> 8) + (n & 0x00FF00FF);

//0xFFFF0000,0x0000FFFF分别是以“16位”为单位提取奇偶位
n = ((n & 0xFFFF0000) >> 16) + (n & 0x0000FFFF);

return n;
}

int main()
{
int m = 56;
count_bits(m);
cout << count_bits(m) << endl;
}

应该是4,但是编译结果是3.
zhoushunda960 2009-12-04
  • 打赏
  • 举报
回复
其实就是将步骤细化。
第一步先求出每两位有多少个1.
第二步根据第一步的结果求每四位有多少个1
第三步根据第二步的结果求每八位有多少个1

。。。。。。
直到最后得出结果。
pw_Start 2009-12-04
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 litaoye 的回复:]
帮LZ搜索了1个log(n)的,效率比较稳定,比那个n&(n-1)平均效率好一些,
另外改一改int64也适用,这样的话,6次就可以算8个256的,也不错了!

int count_bits(unsigned long n)
{
    //0xAAAAAAAA,0x55555555分别是以“1位”为单位提取奇偶位
    n = ((n & 0xAAAAAAAA) >> 1) + (n & 0x55555555);

    //0xCCCCCCCC,0x33333333分别是以“2位”为单位提取奇偶位
    n = ((n & 0xCCCCCCCC) >> 2) + (n & 0x33333333);

    //0xF0F0F0F0,0x0F0F0F0F分别是以“4位”为单位提取奇偶位
    n = ((n & 0xF0F0F0F0) >> 4) + (n & 0x0F0F0F0F);

    //0xFF00FF00,0x00FF00FF分别是以“8位”为单位提取奇偶位
    n = ((n & 0xFF00FF00) >> 8) + (n & 0x00FF00FF);

    //0xFFFF0000,0x0000FFFF分别是以“16位”为单位提取奇偶位
    n = ((n & 0xFFFF0000) >> 16) + (n & 0x0000FFFF);

    return n;
}
[/Quote]
不明白其中的道理。。
zhoushunda960 2009-12-04
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 litaoye 的回复:]
帮LZ搜索了1个log(n)的,效率比较稳定,比那个n&(n-1)平均效率好一些,
另外改一改int64也适用,这样的话,6次就可以算8个256的,也不错了!

int count_bits(unsigned long n)
{
    //0xAAAAAAAA,0x55555555分别是以“1位”为单位提取奇偶位
    n = ((n & 0xAAAAAAAA) >> 1) + (n & 0x55555555);

    //0xCCCCCCCC,0x33333333分别是以“2位”为单位提取奇偶位
    n = ((n & 0xCCCCCCCC) >> 2) + (n & 0x33333333);

    //0xF0F0F0F0,0x0F0F0F0F分别是以“4位”为单位提取奇偶位
    n = ((n & 0xF0F0F0F0) >> 4) + (n & 0x0F0F0F0F);

    //0xFF00FF00,0x00FF00FF分别是以“8位”为单位提取奇偶位
    n = ((n & 0xFF00FF00) >> 8) + (n & 0x00FF00FF);

    //0xFFFF0000,0x0000FFFF分别是以“16位”为单位提取奇偶位
    n = ((n & 0xFFFF0000) >> 16) + (n & 0x0000FFFF);

    return n;
}
[/Quote]

效率确实高,不过太变态了。实在是强!
绿色夹克衫 2009-12-04
  • 打赏
  • 举报
回复
帮LZ搜索了1个log(n)的,效率比较稳定,比那个n&(n-1)平均效率好一些,
另外改一改int64也适用,这样的话,6次就可以算8个256的,也不错了!

int count_bits(unsigned long n)
{
//0xAAAAAAAA,0x55555555分别是以“1位”为单位提取奇偶位
n = ((n & 0xAAAAAAAA) >> 1) + (n & 0x55555555);

//0xCCCCCCCC,0x33333333分别是以“2位”为单位提取奇偶位
n = ((n & 0xCCCCCCCC) >> 2) + (n & 0x33333333);

//0xF0F0F0F0,0x0F0F0F0F分别是以“4位”为单位提取奇偶位
n = ((n & 0xF0F0F0F0) >> 4) + (n & 0x0F0F0F0F);

//0xFF00FF00,0x00FF00FF分别是以“8位”为单位提取奇偶位
n = ((n & 0xFF00FF00) >> 8) + (n & 0x00FF00FF);

//0xFFFF0000,0x0000FFFF分别是以“16位”为单位提取奇偶位
n = ((n & 0xFFFF0000) >> 16) + (n & 0x0000FFFF);

return n;
}
ytytyt8801 2009-12-04
  • 打赏
  • 举报
回复
oo 2009-12-04
  • 打赏
  • 举报
回复
2, &操作后查4次表
zhoushunda960 2009-12-04
  • 打赏
  • 举报
回复
剩下的,对于上面两道题就很简单了。
zhoushunda960 2009-12-04
  • 打赏
  • 举报
回复
判断一个自己有几个1

。。。。。。
//k为要判断的数
//count为k中1的个数
while(k)
{
k = k & (k - 1);
count++;
}
。。。。。。


fire_woods 2009-12-04
  • 打赏
  • 举报
回复
做個0-255的表, 記錄每個char的1的個數

第一題就是查10次表,
第二題就是查8次表, over.
zhengjiankang 2009-12-04
  • 打赏
  • 举报
回复
既然第一个是1个字节1个字节的判断
第二个也可以把两个变量按位与了之后转换成4个char型变量
每个用第一题的方法去判断然后加起来了。
zhengjiankang 2009-12-04
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 gbb21 的回复:]
1: 严格O(n)吧,做个256长度的数组,每个元素表明当前下标的1的个数,然后循环一下即可。
2:&之后再二分count
[/Quote]

第一个好像是编程之美上的原问题吧,不过那个问题是1字节了
你这个256改都不改下就拿过来了?
affss 2009-12-04
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 litaoye 的回复:]
帮LZ搜索了1个log(n)的,效率比较稳定,比那个n&(n-1)平均效率好一些,
另外改一改int64也适用,这样的话,6次就可以算8个256的,也不错了!

int count_bits(unsigned long n)
{
    //0xAAAAAAAA,0x55555555分别是以“1位”为单位提取奇偶位
    n = ((n & 0xAAAAAAAA) >> 1) + (n & 0x55555555);

    //0xCCCCCCCC,0x33333333分别是以“2位”为单位提取奇偶位
    n = ((n & 0xCCCCCCCC) >> 2) + (n & 0x33333333);

    //0xF0F0F0F0,0x0F0F0F0F分别是以“4位”为单位提取奇偶位
    n = ((n & 0xF0F0F0F0) >> 4) + (n & 0x0F0F0F0F);

    //0xFF00FF00,0x00FF00FF分别是以“8位”为单位提取奇偶位
    n = ((n & 0xFF00FF00) >> 8) + (n & 0x00FF00FF);

    //0xFFFF0000,0x0000FFFF分别是以“16位”为单位提取奇偶位
    n = ((n & 0xFFFF0000) >> 16) + (n & 0x0000FFFF);

    return n;
}
[/Quote]

实在是高,可惜这个一点点也看不懂,真晕啊。
affss 2009-12-04
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 zhoushunda960 的回复:]
判断一个自己有几个1
C/C++ code
。。。。。。//k为要判断的数//count为k中1的个数while(k)
{
k= k& (k-1);
count++;
}
。。。。。。


[/Quote]

太厉害了,能看懂一点点!想不明白是什么原理。谢谢啊!
gbb21 2009-12-04
  • 打赏
  • 举报
回复
1: 严格O(n)吧,做个256长度的数组,每个元素表明当前下标的1的个数,然后循环一下即可。
2:&之后再二分count

33,028

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧