如果两个算法都具有O(1)的性能,为什么一个算法比另一个算法快



如果我有一个非常大的数字X,(978678567445456455878909099775523213255436445691200897623461676543789287 948754875435250392049320487584759329 454754875487589457244076477592458249)

我有两个算法可以计算输入数是否可以被4整除(即n%4==0)。既然模运算取O(1),为什么一个算法比另一个算法好呢。我怎么能证明只比较最后两位数字(2)的那个实际上比另一个好呢?

算法1:

n:= Input 
if n divisible by 4, let output :=0 
else output :=1

算法2:

m:=last two digits of input n
if m divisible by 4, let output:=0 
else output:=1
  1. 算法1不是O(1)。它的运行时间与输入数字的位数成正比,因此它是O(log n)。

  2. 谈论具有恒定输入的函数的运行时间是没有意义的。运行时间是关于渐近性的,而不是关于一个特定实例需要多长时间。

  3. 大O表示法不区分常量。相反,只有当两个运行时间在彼此的恒定倍数内时,它们才是"相同的"。换句话说,即使两个算法可能有"相同"的大O符号(如果我们想更精确的话,实际上是大θ符号),在渐近的情况下,其中一个可能比另一个快常数倍。

根据密钥类型的不同,C++Map在为小型数据集查找内容方面比Hash快得多。Map是O(logn),Hash是O(1)。原因是Big O正在处理算法的渐近性能,即如果我们用N的某个不断增加的值来绘制算法的性能,它会接近什么曲线。

当我们散列字符串之类的东西时,我们可能会依次计算每个字节。这可能是10或100个字节,我们需要执行某种形式的计算,以找到存储项目的存储桶。但是请注意,此计算是固定大小的。随着字符串N的数量增加,它决不会影响哈希的计算,即N不会影响查找bucket和插入项的时间。如果将其绘制为N,则会增加散列函数和定位bucket的时间,即O(1)

当我们使用Map时,我们需要将每个字符串与树中的下一个字符串进行比较。这一次,当我们向树中添加字符串时,我们有更多的字符串需要与之进行比较,即随着N的增加,我们在某种程度上影响了查找或插入字符串所需的比较量。当Map中有几个字符串时,这实际上比Hash更快(注意,几年前我使用C++和Url,不确定现在是否仍然一样)。这是因为对于少数字符串,它需要做的工作比Hash少。这一次,因为它是一个二叉树,我们有一个对数影响,即所需的计算量正在增加,如果你绘制它,你会发现它遵循对数曲线,即O(logn)。

原因是Big O不是关于固定大小的数据集,而是关于描述算法随着N的增加而产生的行为。

相关内容

最新更新