如何理解代码:计算范围内的1的数量(0:a)

时间:2012-05-10 15:05:41

标签: algorithm recurrence

我看到一个代码,用于计算范围(0,a)中所有整数的1位总数。

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

我可以理解count函数,但实际上无法理解求解中的重现:

if (a%2 ==1)
   solve(a) = (a+1)/2 + 2* solve(a/2)

有没有人可以解释一下呢?非常感谢。

1 个答案:

答案 0 :(得分:2)

假设您有号码n = 2X+1,并且想要找到

solve(n) = sum of count(i) for 0<=i<=n

这等于:

solve(n) = sum of count(2j)+count(2j+1) for 0<=j<=X

count(2j+1) = count(2j)+1count(2j) = count(j)以来,您可以简化为:

solve(n) = sum of 2*count(2j)+1 for 0<=j<=X
         = sum of 2*count(j)+1 for 0<=j<=X
         = 2*(sum of count(j) for 0<=j<=X) + (sum of 1 for 0<=j<=X)
         = 2*solve(X) + X + 1
         = 2*solve(floor(n/2)) + (n+1)/2

你的复发关系是什么。

如果n是偶数(因此不是2X+1形式),则可以使用公式

solve(n) = count(n) + solve(n-1)

直接来自solve的定义,作为上述总和。