【问题标题】:Counting 1s in the two's complement representations of integers in range[x,y]在 range[x,y] 中整数的二进制补码表示中计数 1
【发布时间】:2012-04-17 15:27:19
【问题描述】:

我的问题与论坛上的一个问题有关 - Number of 1s in the two's complement binary representations of integers in a range 我没有“添加评论”。所以我在这里问 问题是在以 2 的补码形式写下所有数字时计算 1 的数量,这些数字在两个输入数字指定的范围内 解决方案发布在https://gist.github.com/1285119 如下

long long solve(int a)
  {
  if(a == 0) return 0 ;
  if(a % 2 == 0) return solve(a - 1) + __builtin_popcount(a) ;
  return ((long long)a + 1) / 2 + 2 * solve(a / 2) ;
  }


 long long solve(int a,int b)
 {
  if(a >= 0)
  {
   long long ret = solve(b) ;
   if(a > 0) ret -= solve(a - 1) ;
   return ret ;
   }
 long long ret = (32LL * -(long long)a) - solve(~a) ;
 if(b > 0) ret += solve(b) ;
 else if(b < -1)
 {
  b++ ;
  ret -= (32LL * -(long long)b) - solve(~b) ;
 }
return ret ;
}

当输入为 4 //测试用例数

-1 //第一个数字 -2 //第二个数字 输出 0

-1 -3 输出 -31

-3 -5 输出 -30 //1 的个数怎么可能是 -30

1 2 输出 2

由于代码作为 Codesprint 解决方案发布在 InterviewStreet 上,并且在这个论坛上获得了高度投票的答案。它应该是正确的。 谁能解释一下这条线背后的逻辑 long long ret = (32LL * -(long long)a) -solve(~a) in solve(int a,int b) 而#define INF (int)1e9 //不使用时设置无穷大的目的是什么?

【问题讨论】:

标签: c++ algorithm binary


【解决方案1】:

输入错误的结果

-1 -2
-1 -3
-3 -5

是因为程序假定这两个限制是按升序输入的并且不进行检查,因此输入不符合预期会产生错误的结果。一个简单的

if (b < a) {
    int temp = a;
    a = b;
    b = temp;
}

int solve(int a, int b) 的开头将使它返回正确的结果,以任何顺序输入。

long long ret = (32LL * -(long long)a) - solve(~a) 背后的逻辑是(二进制补码)n 的按位补码是~n = (-n)-1。从 a 到 -1 的数字中的总位数(0 或 1) - 包括两者 - 如果 a &lt; 0,则为 32 * |a|。从该计数中,我们减去这些数字中 0 位的总数,即按位补码中 1 位的总数。这些按位补码是从 0 到 |a| - 1 = ~a 的数字,包括这两个数字,其中 1 位的计数由 solve(|a| - 1) = solve(~a) 给出。

【讨论】:

    猜你喜欢
    • 2011-12-18
    • 1970-01-01
    • 1970-01-01
    • 2021-04-20
    • 2015-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多