给出从M到N的整数范围,其中 M和N可能不是2的幂。是否有 有效的方法来计算每个的次数 位设置了吗?
例如0到10的范围
0 0000
1 0001
2 0010
3 0011
4 0100
5 0101
6 0110
7 0111
8 1000
9 1001
10 1010
我想在每一列中设置每个位的时间计数,在这种情况下为3,4,5,5。
答案 0 :(得分:6)
每个位级别都有2^power
0s后跟2^power
1s的模式。
所以有三种情况:
当M
和N
是M = 0 mod 2^(power+1)
和N = 2^(power+1)-1 mod 2^(power+1)
时。在这种情况下,答案只是(N-M+1) / 2
M
和N
当整数除以2^(power+1)
时,M和N都是相同的数字。在这种情况下,有几个子类:
M
和N
都是M
和N
=整数除以2^(power)
时的相同数字。在这种情况下,如果是N < 2^(power) mod 2^(power+1)
,则答案为0
,否则答案为N-M+1
N - (N/2^(power+1))*2^(power+1) + 2**(power)
(整数除法)N > 2^(power) mod 2^(power+1)
,否则答案是(M/2^(power+1))*2^(power+1) - 1 - M
最后一种情况是当整数除以2^(power+1)
时,M和N =不同的数字。在这种情况下,您可以结合使用1和2的技巧。查找M
和(M/(2^(power+1)) + 1)*(2^(power+1)) - 1
之间的数字数。然后在(M/(2^(power+1)) + 1)*(2^(power+1))
和(N/(2^(power+1)))*2^(power+1)-1
之间。最后是(N/(2^(power+1)))*2^(power+1)
和N
。
如果这个答案中存在逻辑错误,请告诉我,这很复杂,我可能会略微搞砸了。
更新:
python实现
def case1(M, N):
return (N - M + 1) // 2
def case2(M, N, power):
if (M > N):
return 0
if (M // 2**(power) == N // 2**(power)):
if (N % 2**(power+1) < 2**(power)):
return 0
else:
return N - M + 1
else:
if (N % 2**(power+1) >= 2**(power)):
return N - (getNextLower(N,power+1) + 2**(power)) + 1
else:
return getNextHigher(M, power+1) - M
def case3(M, N, power):
return case2(M, getNextHigher(M, power+1) - 1, power) + case1(getNextHigher(M, power+1), getNextLower(N, power+1)-1) + case2(getNextLower(N, power+1), N, power)
def getNextLower(M, power):
return (M // 2**(power))*2**(power)
def getNextHigher(M, power):
return (M // 2**(power) + 1)*2**(power)
def numSetBits(M, N, power):
if (M % 2**(power+1) == 0 and N % 2**(power+1) == 2**(power+1)-1):
return case1(M,N)
if (M // 2**(power+1) == N // 2**(power+1)):
return case2(M,N,power)
else:
return case3(M,N,power)
if (__name__ == "__main__"):
print numSetBits(0,10,0)
print numSetBits(0,10,1)
print numSetBits(0,10,2)
print numSetBits(0,10,3)
print numSetBits(0,10,4)
print numSetBits(5,18,0)
print numSetBits(5,18,1)
print numSetBits(5,18,2)
print numSetBits(5,18,3)
print numSetBits(5,18,4)
答案 1 :(得分:0)
它可以像 -
一样简单取x1 = 0001(在最右边的列找到1),x2 = 0010,x3 = 0100等等..
现在,在一个循环中 -
n1 = n2 = n3 = 0
for i=m to n:
n1 = n1 + (i & x1)
n2 = n2 + (i & x2)
n3 = n3 + (i & x3)
其中 - ni =第i列中的1的数字(从右起)