【发布时间】:2019-02-21 07:27:56
【问题描述】:
从时间效率的角度来看,Russian peasant multiplication算法是用n乘m还是m乘n有关系吗?
比如,计算26*47时,时间效率和计算47*26差不多吗?
【问题讨论】:
标签: algorithm language-agnostic
从时间效率的角度来看,Russian peasant multiplication算法是用n乘m还是m乘n有关系吗?
比如,计算26*47时,时间效率和计算47*26差不多吗?
【问题讨论】:
标签: algorithm language-agnostic
由于算法运行floor(log2(k)) 迭代以获取k 的乘数(第一个数字),因此运行时间肯定取决于顺序。如果n 和m 位于相同的两个连续两个幂之间,那么它们将需要相同数量的迭代来完成。否则,请始终将较小的数字放在第一位,以最大限度地减少运行时间。
【讨论】:
unsigned int russianPeasant(unsigned int a, unsigned int b) {
int res = 0; // initialize result
// While second number doesn't become 1
while (b > 0)
{
// If second number becomes odd, add the first number to result
if (b & 1)
res = res + a;
// Double the first number and halve the second number
a = a << 1;
b = b >> 1;
}
return res;
}
算法在b变为0时退出while循环。循环运行的次数为[log2(b)] + 1次。
而且移位几乎需要恒定的时间(1 个 CPU 周期)
使用较小的值作为 b 调用是有意义的。
奖励:速度比较
我编写了上面的代码,并在循环中运行相同的数字 47 和 26 10**8 次。
a = 26, b=47,平均耗时 1336852.2 微秒。
a = 47, b=26,平均耗时 1094454.4 微秒。
有趣的旁注:
尽管正如@Dillon Davis 提到的,如果它们的日志相同,它应该需要相同数量的迭代,但我发现它仍然需要更少的时间,因为 b 的数量较小。
(所有时间以微秒为单位)
a = 46,b = 36 - 1204240.6
a = 36, b = 46 - 1295766.8
a= 44, b = 36 - 1204266.2
a= 36,b = 44 - 1253821.17。
TLDR: 以较小的第二个数字运行(while 循环中的那个)
源码来自:https://www.geeksforgeeks.org/russian-peasant-multiply-two-numbers-using-bitwise-operators/
【讨论】:
这取决于您如何实现俄罗斯农民算法。可以是:
a*b 更快b*a 更快我选择没有区别,因为实数的数学乘法是可交换的:a*b=b*a 并且因为最终用户在调用您的函数时不喜欢关心参数的顺序
为此,您需要调整您的代码,例如:
Let the two given numbers be 'a' and 'b'.
1) If 'b' is greater than 'a' - swap 'a' with 'b'
2) Initialize result 'res' as 0.
3) Do following while 'b' is greater than 0
a) If 'b' is odd, add 'a' to 'res'
b) Double 'a' and halve 'b'
4) Return 'res'.
这段代码会很复杂
O(log₂(min(a,b)))
【讨论】: