已知具有时间复杂度O(n^2)
的递归Karatsuba乘法算法比具有复杂度O(n log(n))
的简单乘法算法更快。
但是,它比“schoolgrade”算法使用更多的内存空间 - O(n)
而不是O(n)
内存,这对于具有少量内存的控制器或非常小的计算机来说非常关键。
所以,我的问题是:
有没有办法在karatsuba算法中实现O(n log(n))
内存空间?
PS:我知道使用FFT可以实现更快的速度O(n)
和更好的内存使用public static class URLLinkHelper
{
public static MvcHtmlString URLLink(this HtmlHelper htmlHelper, string linkText, string url)
{
TagBuilder tagBuilder = new TagBuilder("a");
tagBuilder.Attributes["href"] = url;
tagBuilder.InnerHtml = linkText;
return new MvcHtmlString(tagBuilder.ToString());
}
}
,但我只是对Karatsuba感到好奇。
答案 0 :(得分:3)
Karatsuba的算法只需要O(n)空间。
(A0 2^n + B0)(A1 2^n + B1)
= A0 A1 2^(2n) + B0 B1 + ((A0+B0)(A1+B1) - A0 A1 - B0 B1)2^n
这是一个粗略的归纳论证。归纳地,假设使用Karatsuba算法乘以n位数只需要cn空间。要乘以2n位数,我们可以在cn空间中乘以A0 A1,然后在2n空间中保存答案,然后在cn空间中将B0 B1相乘,然后将答案保存在2n空间中,然后乘以( cn空间中的A0 + B0)(A1 + B1)。此时我们最多使用(c + 4)n个空格。然后我们执行减法并在4n空间中记录答案。峰值空间使用量为(c + 4)n,小于max(c,4)(2n)空间。因此,只要c> 4,如果需要cn空间来乘以n位数,则需要c(2n)空间乘以2n位数。这是不精确的,因为(A0 + B0)和(A1 + B1)可能有n + 1位而不是n。因此,严格的归纳论证更加混乱,但可以遵循相同的基本模式。
问题的前提是错误的。 Karatsuba乘法仅需要O(n)空间,而不是Omega(n log n)。某些实现可能需要更多空间,不一定限于O(n log n),例如,如果您并行执行计算。
事实上,除了答案之外,可以在O(log n) extra bits中进行Karatsuba乘法。
答案 1 :(得分:1)
答案是肯定的
可以使用输入数组的N个条目和输出数组的2 * N个条目就地执行“ Karatsuba”算法,从而节省每次递归的额外内存。
在这里查看示例: https://github.com/hselasky/libmbin/blob/master/mbin_multiply_x3.c
-HPS