如何解决如何找到算法的时机?
我正在学习如何找到算法的运算时间,但是在这张照片中我没有得到1 + 2n + 2(n-1)的含义。 这些方程式的来源
解决方法
因此,基本上,那些幻灯片的作者认为,即使它们不够准确,尝试更加“准确”也是个好主意(尝试可能是个坏主意)。
第1行
for (i = 0; i < n-1; i++)
i = 0
仅执行一次(我们不会继续初始化i
)。因此算为:
1
i < n-1
在循环开始之前,每次迭代之间以及最后一次迭代之后执行(这就是它知道如何退出的方式)。因此算为:
迭代次数+ 1
= num_elements {0,...,n-2} + 1
=(n-1)+1
= n
i++
在每次迭代后执行(这次不在第一次迭代中执行)。因此算为:
迭代次数 = n-1
全部:
(1)+(n)+(n-1)
现在,这与您的演讲幻灯片上的内容不同,因为您的讲师已经决定:i < n-1
真的是:int tmp_max = n - 1; i < tmp_max;
因此,他们认为这实际上是两个操作,即使编译器仅会(在循环之前)仅一次计算此值。对于像你这样的学生来说,这也不必要地使事情变得混乱。
他们还必须认为:i++
真的是i = i + 1
或者换句话说:
int tmp_i = i + 1; i = tmp_i
同样,他们误解了c / c ++编译器的工作方式。如今,i++
始终等同于++i
,后者不使用任何临时值,因此仅在一个时钟周期内发生。
困惑吗?当您学习复杂性理论时,您不必理会这些东西。一次加法仅需要一个时钟周期,但是在大多数现代CPU上,除法大约需要5个时钟周期,但是我怀疑您的老师希望您考虑使用那个。在研究复杂性时,您不应该在研究处理器。复杂度理论的全部要点是,您不必关心这些乘法常数。
我们关心的是i
从0
到n
(谁关心n-1
),并且这一行的复杂度是:>
O(n)。
第2行
for (j = 0; j < n-i-1; j++)
在他们对乘法常数的决策中,存在同样的错误推理,这一次,您的老师将每个j < n-i-1
视为3次运算。
对于内部而言,这是有道理的,只是作者未能分开问题。
相反,我们应该 first 计算此行的复杂度,就像i
是一个常数一样:
1 +(n-i)+(n-i) = O(n-i)
后来请记住,j
的值将从0
到n-i
。
剩余的行
这些是固定时间。无论n
,i
或j
的值如何,程序都只能执行if
语句,也可以执行全部4行。
O(1)
在一起:
外循环,i = {0,...,n},O(n)
内部循环,j = {0,...,n-i},O(n-i)
内循环,O(1)
让我们删除我们的模块化并认识到i
不是常数:
两个循环的复杂度= O(n-0)+ O(n-1)+ ... + O(0)
= O(1 + 2 + 3 ... + n)
= O(n(n + 1)/ 2)
= O(n ^ 2)
我猜您已经知道how to find the sum的人:
1 + 2 + 3 ... + n
那么内循环执行了多少次?与第二个循环的迭代次数相同-由于其内容的复杂性与循环的复杂性无关,因此我们可以乘以:
总体复杂度= O(n ^ 2)* O(1)
= O(n ^ 2)
我希望我对计算模块化的解释会有所帮助。对于较大的示例-特别是真实的代码库,它非常有用。多数情况下,您在模块化组件之间没有依赖关系,因此您可以添加或乘以这些组件-希望我已经证明,即使您具有依赖关系,模块化仍然有用。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。