今天,我听说过Karatsuba算法,一种快速乘法算法。我很好奇这种“快速”意味着什么?
通常,在计算一段代码的时间复杂度时,我们考虑使用*运算符作为O(1)的乘法运算,如果它始终为真,那么为什么我们有一个关于渐近符号的更快的算法?或者*在非常大的数字上执行时不应该被认为是O(1),其中Karatsuba算法可能有用吗?
在机器级别,编译器总是对*进行一些优化。例如,使用逐位运算将数字乘以2 ^ n。 Karatsuba算法在实际运行时间内是否超过*?
答案 0 :(得分:4)
经典乘法是O(n 2 ),其中 n 是乘以的数字中的位数。
当测量普通计算机代码时,你正在处理固定大小(通常是32位或64位)数字,因此变为O(1)(因为大小不会改变)
一旦开始处理BigIntegers,这就变得非常重要。
答案 1 :(得分:1)
此算法属于长数字。 CPU中的寄存器大小越长。 这来自维基百科:
Karatsuba算法是一种快速乘法算法。它是 由Anatolii Alexeevitch Karatsuba于1960年发明并于2006年出版 它将两个n位数的乘法减少到最多3 n ^(log_2 3)= 3 n ^ 1.585个单位乘法 通常(当n是2的幂时,恰好是n ^(log_2 3)。
答案 2 :(得分:1)
这个问题的问题在于,您调用的*
运算符不是算法。它完全由编译器(或解释器)和CPU组成,以确定它是如何得出答案的。
我不确定使用内置多重化是O(1)的说法,但除非输入有一些限制,否则不可能是真的(也许N必须足够小)适合CPU寄存器)或使用某些查找表。
正如SLaks提到的那样,在CPU中发生乘法运算时(对于大多数CPU而言),数字总是相同的大小,32位或64位。即使数字1可以用一个比特来表示,它仍占用32位空间(在大多数实现中)
Big-O表示法只是告诉您存在一定大小的输入,之后一个更有效的算法(以Big-O术语表示)将比效率较低的算法更快。
Bitshifting不能应用于所有任意乘法,所以实际上它很有用,从算法上来说,它只能与仅适用于乘以2的幂的其他方法进行比较。
大多数语言都有一种特殊类型用于处理大于32位的数字,甚至有可能在使用*
进行乘法时使用Karatsuba算法。