posts - 456,  comments - 803,  views - 82万
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

在面试中被问到这一题:判断32位无符号整数二进制中1的个数,虽然不难,但要求层层优化。现在整理一下:
1、基本思路:

#include <iostream>

using namespace std;

int findone(unsigned int n){
  
for(int i=0;n>0;n>>=1)
    i
+=(n&1);
  
return i;
}


int main(){
  
int n;
  cin
>>n;
  cout
<<findone(n)<<endl;
  
return 0;
}
2、优化:
这样的时间复杂度是T(m)=m,取决于二进制数的位数m。如果要求在更短时间内求出,应该如何做呢?如果findone函数被反复调用(成千上万次调用),那应该怎么优化呢?
其实就是空间换时间的思想:可以预建立一个表,存放了从0~2^32每个数中1的个数,用时去查一下表就知道了。但这样显然要耗费很多的空间(至少2^32/(256/32)=512MB,哈哈,正是一般内存大小)。于是需要再优化:存放0-255每个数中1的个数,然后分段查询。如下面把32位数分为4段,每段一个字节,所以有一个256大小供查询的表:
char tOne[256]="\0\1\1\2\1\2……"//后面省略

int findone(unsigned int n){
  
for(int i=0;n>0;n>>=8)
    i
+=tOne[n&255];
  
return i;
}

3、据说Intel中有条汇编指令(或是数条)即可完成这个工作,但不知道具体是什么,应该怎样做。
4、又看到有道MS的笔试题殊途同归:
int func(unsigned int n){
  
int count=0;
  
while(n>0){
    n
&=(n-1);
    count
++;
  }

  
return count;
}

posted on   小生杂谈  阅读(3763)  评论(2编辑  收藏  举报
编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 字符编码:从基础到乱码解决
点击右上角即可分享
微信分享提示