Algorithm 是否可以在O(1)中计算数字中的设置位数?

Algorithm 是否可以在O(1)中计算数字中的设置位数?,algorithm,Algorithm,我是在一次采访中被问到上述问题的,采访者对答案非常肯定。但我不确定。有人能帮我吗 当然。显而易见的暴力方法只是一个大的查找表,输入数字的每个可能值都有一个条目。如果这个数字很大,那就不太实际,但仍然足以证明这是可能的 编辑:有人认为这完全是胡说八道,基本上任何算法都是如此 在一定程度上,这是一个公平的说法——但限制是如此严重,以至于对于大多数算法来说,它仍然毫无意义 我最初的观点(至少和我记得的一样)是,人口计数大约等同于许多其他运算,比如我们通常假设为O(1)的加法和减法 在硬件级别,单周期P

我是在一次采访中被问到上述问题的,采访者对答案非常肯定。但我不确定。有人能帮我吗

当然。显而易见的暴力方法只是一个大的查找表,输入数字的每个可能值都有一个条目。如果这个数字很大,那就不太实际,但仍然足以证明这是可能的

编辑:有人认为这完全是胡说八道,基本上任何算法都是如此

在一定程度上,这是一个公平的说法——但限制是如此严重,以至于对于大多数算法来说,它仍然毫无意义

我最初的观点(至少和我记得的一样)是,人口计数大约等同于许多其他运算,比如我们通常假设为O(1)的加法和减法

在硬件级别,单周期
POPCNT
指令的电路可能比单周期
ADD
指令的电路更简单。仅举一个例子,对于任何实际大小的数据字,我们都可以对4位块并行使用表查找,然后将这些块的结果相加。即使使用不太可能的最坏情况假设(例如,每个表都有单独的存储),这仍然很容易在现代CPU中实现——事实上,它可能至少比上面提到的单周期加法或减法简单一些1

这与许多其他算法形成了鲜明的对比。举一个明显的例子,让我们考虑排序。即使是大多数人能想象到的最简单的排序——2项,每个8位,我们已经在一个64KB的查找表中获得恒定的复杂性。早在我们能够做一个相当简单的排序(例如,100项)之前,我们就需要一个包含比宇宙中原子多得多的数据项的查找表

从相反的方向来看,在某个点上,基本上没有什么是O(1)了,这是肯定的。让我们考虑可能的最微不足道的操作。对于N位CPU,按位
通常作为一组N
门并行实现。与加法不同,一个位和另一个位之间没有交互,因此对于任何实际大小的CPU,这都很容易在一条指令中执行

尽管如此,如果我指定一个按位的
,其中每个操作数为100 PB,那么即使是以恒定的复杂度来完成这项工作,也没有什么切实可行的方法。使用通常的并行
门的方法,我们最终得到了(除其他外)300 PB的输入和输出线——这个数字甚至使最大CPU上的管脚数都相形见绌

在合理的硬件上,对100 PB操作数执行按位
操作需要一段时间(更不用说相当多的硬盘空间)。如果我们将其增加到200 PB的操作数,时间可能(大约)增加一倍——因此从这个角度来看,这是一个O(N)运算。很明显,其他“琐碎”操作(如加法、减法、逐位
、逐位
异或
)也是如此

尽管如此,除非你有非常具体的指令说你将要处理非常巨大的操作数,否则你通常会把每一个操作都当作一个恒定复杂度的操作。从这些术语来看,就在固定时间内执行的难度而言,POPCNT指令介于按位
/
/
异或
和加法/减法之间


一,。您可能想知道,当它在执行一些其他操作后实际包含一个
add
时,它怎么可能比
add
更简单。如果是这样的话,那真是个好问题

答案是,这是因为它只需要一个小得多的加法器。例如,64位CPU需要一个半加器和63个全加器。在这个简单的实现中,执行逐位加法——即,将一个操作数的0位与另一个操作数的0位相加。它生成一个输出位和一个进位。该进位成为下一对位加法的输入。在某种程度上,有一些技巧可以将其并行化,但野兽的本质(可以说)是位串行的

对于POPCNT指令,在执行单独的表查找之后,我们有一个加法,但我们的结果仅限于输入字的大小。给定相同大小的输入(64位),我们的最终结果不能大于64。这意味着我们只需要一个6位加法器而不是64位加法器


由于如上所述,加法基本上是位串行的,这意味着
POPCNT
指令末尾的加法基本上比普通加法快得多。具体来说,它在操作数大小上是对数的,而简单加法在操作数大小上大致是线性的。

当然。显而易见的暴力方法只是一个大的查找表,输入数字的每个可能值都有一个条目。如果这个数字很大,那就不太实际,但仍然足以证明这是可能的

编辑:有人认为这完全是胡说八道,基本上任何算法都是如此

在一定程度上,这是一个公平的说法——但限制是如此严重,以至于对于大多数算法来说,它仍然毫无意义

我最初的观点(至少和我记得的一样)是,人口计数大约等同于许多其他运算,比如我们通常假设为O(1)的加法和减法

在硬件级别,单周期
POPCNT
指令的电路可能比单周期
ADD
指令的电路更简单。仅举一个例子,对于任何实际大小的数据字,我们都可以在4上使用表查找