【发布时间】:2020-05-26 23:40:18
【问题描述】:
我正在查看这个设置位计数页面:https://www.geeksforgeeks.org/count-set-bits-in-an-integer/
最后一个算法用位映射数字说:它只是维护一个数字到位的映射(或数组)以用于半字节。一个半字节包含 4 个位。所以我们需要一个最多 15 个的数组。
int num_to_bits[16] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
现在我们只需要递归地获取给定的 long/int/word 等的半字节。
num_to_bits =[0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4];
# Recursively get nibble of a given number
# and map them in the array
def countSetBitsRec(num):
nibble = 0;
if(0 == num):
return num_to_bits[0];
# Find last nibble
nibble = num & 0xf;
# Use pre-stored values to find count
# in last nibble plus recursively add
# remaining nibbles.
return num_to_bits[nibble] + countSetBitsRec(num >> 4);
num = 31
from timeit import default_timer as timer
t1 = timer()
print(countSetBitsRec(num))
t2 = timer()
print(t2-t1)
num = 421342356246244235625423523626342453143523624526434636546745745634523546346346346346344506546456909546540964596956306030963068359683578753068340634960340683463906835096835068309683486036830563596
t1 = timer()
print(countSetBitsRec(num))
t2 = timer()
print(t2-t1)
t1 = timer()
print(bin(num).count('1'))
t2 = timer()
print(t2-t1)
5
0.00013369599992074654
335
0.00015420899990203907
335
0.00011028399990209437
在时间复杂度部分,它表示时间和内存都是 O(1)。即使两个整数的时间都很接近,我也无法理解这是 O(1) 的情况,因为它正在进行递归调用?
【问题讨论】:
-
很抱歉,geeksforgeeks 是出了名的错误或不精确。这不会是第一次。在这种情况下,他们首先声称整数的长度是可变的(由于机器架构,这在实践中是不正确的)然后他们假设它的长度是一个常数来逃避 O(1)。在这个特定级别上,时间复杂度绝对无关紧要。在这个级别,您只关心有效性能,而不是理论复杂性。
-
是的,我现在明白了。我还认为 64 位整数只有 O(1),但他们没有提到。这真的很混乱。谢谢。
标签: python-3.x bit-manipulation