如果两者都具有 O(1) 的性能,为什么一种算法比另一种算法更快
Why is one algorithm faster than the other if both have performance of O(1)
如果我有一个非常大的数字 X,(978678567445456455878909099775523213255436445691200897623461676543789287 948754875435250392049320487584759329 454754875487589457244076477592458249)
我有两种算法可以计算输入数字是否可以被 4 整除(即 n % 4 == 0)。
由于模运算采用 O(1),如果两者都是 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 不是 O(1)。它的运行时间与输入数的位数成正比,所以是O(logn
).
常量输入函数的运行时间是没有意义的。 运行时间是关于渐近的,而不是关于特定单个实例需要多长时间。
大O表示法不区分常量。相反,两个 运行 时间是 "same" 只有当它们在彼此的常数倍数内时。换句话说,即使两种算法可能具有 "same" 大 O 表示法(如果我们想要更精确的话,实际上是大 theta 表示法),在渐近情况下,一个实际上可能比另一个快常数倍。
根据键类型,C++ Map 在为小型数据集查找内容时比 Hash 快得多。映射是 O(log n),哈希是 O(1)。原因是 Big O 正在处理算法的渐近性能,即如果我们用 N
的某个不断增加的值绘制算法的性能,它接近什么曲线。
当我们散列像字符串这样的东西时,我们可能会依次计算每个字节。这可能是 10 或 100 个字节,我们需要执行某种形式的计算来找到要存储项目的桶。但是请注意,此计算是固定大小的。随着字符串数量 N
的增加,它绝不会影响散列的计算,即 N
不会影响找到桶和插入项目的时间。如果将其绘制为 N
会增加散列函数的时间并找到一个桶是常数,即 O(1)
当我们使用 Map 时,我们需要将每个字符串与树中的下一个字符串进行比较。这一次,当我们向树中添加字符串时,我们有更多的字符串需要与 ie 进行比较,即随着 N
的增加,我们在某种程度上影响了我们需要进行比较的数量,以便找到或插入一个字符串.当 Map 中有几个字符串时,这实际上比 Hash 快(注意,几年前我使用 C++ 和 Urls,不确定现在是否仍然相同)。这是因为对于一些字符串,它需要做的工作比 Hash 做的少。这次因为它是一棵二叉树,我们有一个对数效应,即所需的计算量在增加,如果你绘制它,你会发现它遵循对数曲线,即它是 O(log n)。
原因是 Big O 不是关于固定大小的数据集,而是关于描述随着 N
增加的算法的行为。
如果我有一个非常大的数字 X,(978678567445456455878909099775523213255436445691200897623461676543789287 948754875435250392049320487584759329 454754875487589457244076477592458249)
我有两种算法可以计算输入数字是否可以被 4 整除(即 n % 4 == 0)。 由于模运算采用 O(1),如果两者都是 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 不是 O(1)。它的运行时间与输入数的位数成正比,所以是O(log
n
).常量输入函数的运行时间是没有意义的。 运行时间是关于渐近的,而不是关于特定单个实例需要多长时间。
大O表示法不区分常量。相反,两个 运行 时间是 "same" 只有当它们在彼此的常数倍数内时。换句话说,即使两种算法可能具有 "same" 大 O 表示法(如果我们想要更精确的话,实际上是大 theta 表示法),在渐近情况下,一个实际上可能比另一个快常数倍。
根据键类型,C++ Map 在为小型数据集查找内容时比 Hash 快得多。映射是 O(log n),哈希是 O(1)。原因是 Big O 正在处理算法的渐近性能,即如果我们用 N
的某个不断增加的值绘制算法的性能,它接近什么曲线。
当我们散列像字符串这样的东西时,我们可能会依次计算每个字节。这可能是 10 或 100 个字节,我们需要执行某种形式的计算来找到要存储项目的桶。但是请注意,此计算是固定大小的。随着字符串数量 N
的增加,它绝不会影响散列的计算,即 N
不会影响找到桶和插入项目的时间。如果将其绘制为 N
会增加散列函数的时间并找到一个桶是常数,即 O(1)
当我们使用 Map 时,我们需要将每个字符串与树中的下一个字符串进行比较。这一次,当我们向树中添加字符串时,我们有更多的字符串需要与 ie 进行比较,即随着 N
的增加,我们在某种程度上影响了我们需要进行比较的数量,以便找到或插入一个字符串.当 Map 中有几个字符串时,这实际上比 Hash 快(注意,几年前我使用 C++ 和 Urls,不确定现在是否仍然相同)。这是因为对于一些字符串,它需要做的工作比 Hash 做的少。这次因为它是一棵二叉树,我们有一个对数效应,即所需的计算量在增加,如果你绘制它,你会发现它遵循对数曲线,即它是 O(log n)。
原因是 Big O 不是关于固定大小的数据集,而是关于描述随着 N
增加的算法的行为。