俄罗斯农民乘法算法的时间复杂度?

时间:2015-03-05 21:27:32

标签: c++ algorithm multiplication

我想知道这段代码的时间复杂性是俄罗斯农民实施

unsigned long long int russian(unsigned long long int a, unsigned long long int b) {
    unsigned long long int res = 0;
     while (b > 0) {
        if (b & 1)
            res = res + a;
        a <<= 1;
        b >>= 1;
    }
    return res % mod;
}

据我所知,我认为其时间复杂度为 lg2b lg2a (取决于我们选择 a b )。任何专家评论?

1 个答案:

答案 0 :(得分:3)

您提供的代码片段的时间复杂度当然是O(1),因为它可以花费多长时间的上限,并且永远不会超过任何输入的上限。

据推测,这不是你实际要问的问题的答案。实际上有几个不同的东西你可能真正感兴趣,它们实际上都有不同的答案。

(另外,既然你似乎试图进行模块化乘法运算,你真的应该减少循环中里面的所有相关数量,这样你就不会溢出,所以你可以使用-代替%


您可能对准确估计挂钟时间感兴趣。获得这个实际上需要收集一些经验数据,但它可能看起来像

A + B bitlength(b) + C popcount(b)
对于某些常量popcount1A

B是二进制扩展中C的个数)。但是,CPU硬件实际上相当复杂,实际上可能非常需要对上面的第三项进行良好估计,因为分支预测硬件可能会做一些奇怪的事情。

ABC可能不是常数;它们在某种程度上取决于这个函数是否被内联,以及围绕它使用的地方的代码类型。


现在,您可能需要一个更抽象的答案,其中b可以是任意大小,而不是约束为unsigned long long的大小,并且想要计算算术运算的数量。这显然只是b的位长,或者如评论所示,O(lg(b))。 (其中lg是日志库2)


现在,您可能实际上不仅对算术运算感兴趣,而且对成本感兴趣。并且可能对a具有任意大小而不是约束为unsigned long long感兴趣。一个有用的度量单位是位操作。例如在N位数上向左移1,应该花费O(N)位操作。

我非常确定循环适用于O(lg(a)lg(b)+lg(b)^2)位操作。 (这不包括您之后执行的%操作)