乘法算法用于乘以两个基数r数:
0 <= x,y < r^n
x = x1 * r^(n/2) + x0
y = y1 * r^(n/2) + y0
其中x0
是包含最低有效数字的x
的一半,而x1
是具有最高有效数字的一半,而y
则类似。< / p>
因此,如果r = 10
和n = 4
,我们会x = 9723 = 97 * 10^2 + 23
,其中x1 = 97 and x0 = 23
。
乘法可以完成:
z = x*y = x1*y1 + (x0*y1 + x1*y0) + x0*y0
所以我们现在有四个半数数的乘法(我们最初有一个n位数的乘法,现在我们有四个n/2
个数字的乘法。)
我认为这个算法的重现是:
T(n) = O(1) + 4*T(n/2)
但显然是T(n) = O(n) + 3T(n/2)
无论哪种方式,解决方案都是T(n) = O(n^2)
,我可以看到这一点,但我想知道为什么有一个O(n)术语而不是O(1)
术语?
答案 0 :(得分:1)
你是对的,如果你用天真的计算术语In [1]: response.xpath('//h2[@class="media-heading text-strong"]/text()')
Out[1]: []
In [2]: response.xpath('//h2[@class="media-heading text-strong"]/text()')
Out[2]: []
In [3]: response.xpath('//div/span[.="Contact Name:"]/following-sibling::div[1]/text()')
Out[3]: []
In [4]: response.xpath('//div/span[.="Phone:"]/following-sibling::div[1]/text()')
Out[4]: []
,使用两种产品,时间复杂度是二次的。这是因为我们提供了四种产品,并且按照您的建议,重复发生x0*y1 + x1*y0
,它解决了T(n) = O(n) + 4T(n/2)
。
然而,Karatsuba观察O(n^2)
,我们让xy=z2 * r^n + z1 * r^(n/2) + z0
,z2=x1*y2
和z0=x0*y0
,并且可以将最后一个词表达为z1=x0*y1 + x1*y0
,仅涉及一种产品。使用这个技巧,重复确实变为z1=(x1+x0)(y1+y0)-z2-z0
因为我们完全做了三个产品(而不是四个如果不使用技巧)。
由于数字为T(n) = O(n) + 3T(n/2)
,我们需要r^n
个数字来表示数字(通常,对于固定的n
,我们需要r>=2
个数字来表示数字O(log N)
)。要添加该订单的两个数字,您需要“触摸”所有数字。由于有N
个数字,您需要n
(正式我要说O(n)
,意思是“至少Omega(n)
时间的顺序”,但是让我们将这些细节放在一边)时间计算他们的总和。
例如,在计算产品n
时,位数N*M
将为n
(假设基数max(log N, log M)
不变)。
在Karatsuba algorithm的Wiki页面上更详细地解释了代数技巧。