Python 确定以下编码段的时间复杂度

Python 确定以下编码段的时间复杂度,python,time-complexity,Python,Time Complexity,如何确定此编码段的时间复杂度?我是python新手,非常感谢您的帮助 sum = 0 i = n while (i>= 1): sum += i i /= 2 i = n j = 2 while (i >= 1): sum +=i i /= j j *= 2 我认为第一个循环可能是(logn+2),第二个循环可能是(2logn+4),但我不确定我是否已经接近正确的轨道 这是我的答案。为了在数学上更加精确,你可能应该写不等式,而不是像我那样写等

如何确定此编码段的时间复杂度?我是python新手,非常感谢您的帮助

sum = 0
i = n
while (i>= 1):
    sum += i
    i /= 2
i = n
j = 2
while (i >= 1):
    sum +=i
    i /= j
    j *= 2

我认为第一个循环可能是(logn+2),第二个循环可能是(2logn+4),但我不确定我是否已经接近正确的轨道

这是我的答案。为了在数学上更加精确,你可能应该写不等式,而不是像我那样写等式,但无论如何,整体推理不会改变。 如果有意义或发现错误,请通过评论让我知道

第一圈 第一个循环的迭代次数与使i小于1所需的次数相同

它的时间复杂度是O(logu2(n+1))其中logu2是指基于2的对数

0  i = n
1  i = n / 2
2  i = n / 2 / 2
k  i = n/ 2^k
你会问自己:什么是k,以至于
n=2^k

k = log_2(n)
2k = log_2(n)
k = log_2(n)/2
log_2(n)/2
log_2(sqrt(n))
当然,您不会因为变量var sum而分心,因为变量不会干扰驱动循环的变量

第二圈 第二个循环也是由i除以2的倍数来驱动的,但是每次迭代都要通过乘以
j*2
来加速。它的时间复杂度为logu2(n+1)/2

在每次迭代
k时,j=2^k

在迭代
k+1
j=2^(k+1)

所以迭代
k+1
i/=2^(k+1)

什么是k使得
n=2^(2k)

代码段 这两个循环不是嵌套的,它们之间的i被重置为n,所以它们只是相加

log_2(n+1) + log_2(sqrt(n+1))
log_2(n+1 + sqrt(n+1))

就计算复杂度而言,O(n)表示实际的位长度(他们称n为位长度)

因此,每次i通过第一个循环时,i/=2移动一位。在第二个循环中,i/=j移位1,2,4,8。。。点点滴滴

请记住,您有一个名为n的变量,而我提到的n(输入的位长度)实际上是关于CC理论的约定

因此,假设您编写的脚本只有一个变量重命名:nm

sum = 0

i = m
while (i>= 1):
    sum += i
    i /= 2

i = m
j = 2
while (i >= 1):
    sum +=i
    i /= j
    j *= 2
我刚刚重命名了变量

现在让我们总结一下:

第一个循环具有“逐位”复杂度,因此表示法为O(n)(线性复杂度,每次迭代一位)

编辑:第二个循环的复杂性如下:“在第k个循环中,它将消耗1+2+…+2^(k-1)位:它将消耗2^k-1位”

因此,如果第K个循环消耗了那么多的位,我们说:2^K位的K次迭代。我们说“对数”:O(log2(n))


最后的结果是:O(log2(n))+O(n),它有一个线性顺序,因为n>log(n)。

你能解释一下你为什么这么想吗?如果没有,我们显然只能猜测你是否在正确的轨道上。这与
天篷
有什么关系?因为这显然是家庭作业,请解释你得出结论的理由。此外,这是一个两个独立的问题。问第一个问题,得到一个答案,然后这就是你所需要的,或者你可以为第二个问题发布一个新问题。作为旁注,你不需要也不应该在
while
条件下使用parens。命名一个变量
sum
是个坏主意,因为它隐藏了相同名称的内置函数(您可能想使用它来检查循环的结果)。如果日志演算不清楚,您可以检查log(sqrt n)=1/2 log n=O(log n)。这是正确的。然而,我并没有像OP一样编写大O符号。因此,与其说是渐进分析,不如说是计算步骤。。如果需要,我正在等待编辑反馈。@templatetypedef是否确认我的分析?我有一段时间没做任何事了。等一下。。第一个循环的复杂度与输入的位数成线性关系,而不是一般的输入位数。对吗?因为你在用二进制表示法思考……是的。O(n)不是关于输入数,而是关于输入的位长度。n是log2(m)的四舍五入。另一条评论:重要的是要理解CC是关于位长度的,因为许多与密码学相关的问题在用于密钥的位长度加倍时会使其解析时间(其复杂性)平方。好吧,我们的答案是一致的:)但我没有重命名n=log2(m)毕竟我确实数了数台阶,因为我不确定他想要什么。好把戏,按位;):)。不,我重命名了变量,这样我就可以用符号解释CC,并且在引用代码时不会混淆您。
sum = 0

i = m
while (i>= 1):
    sum += i
    i /= 2

i = m
j = 2
while (i >= 1):
    sum +=i
    i /= j
    j *= 2