我该如何计算算法中的操作数?

时间:2014-12-27 15:54:28

标签: algorithm big-o asymptotic-complexity

搜索完网页后,我找到了以下步骤计数方法。

int mean(int a[], size_t n)
{
    int sum = 0;                 // 1 step * 1
    for (int i = 0; i < n; i++)  // 1 step * (N+1)
        sum += a[i];             // 1 step * N
    return sum;                  // 1 step * 1
}

因此,步数为2N + 3.

然而,在YouTube视频中,我看到,在同样的情况下,他们获得了6N + 4的计数。在该视频中,他们将分配,添加操作计为步骤。

哪种方法正确? Big-O值保持不变,但是,如果有人要求我给他们算法的步数,我应该回答什么?

2 个答案:

答案 0 :(得分:3)

我不知道你在那里算什么,但是,如果算上所涉及的原始操作,那么计算会有所不同。

for()行包含以下操作:

  • i = 0 - 1次操作;
  • i < n - 1次操作,N次;
  • i ++ - 2次操作,N次; i ++i = i + 1的快捷方式,这涉及到添加和分配,因此有2个操作;

接下来,sum += a[i]sum = sum + a[i]的快捷方式,其中包含a[i]地址的计算,这是一个加法(1个操作),加法(sum + a[i])和任务(2个操作)。所有这些都发生N次;

总结那里有6 * N + 2个操作但是,正如其他海报所注意到的那样,这取决于你计算的很多东西。如果你分析编译器为这个源代码生成的汇编代码,你会注意到还有读指令,它们也应该计算在内。

总而言之,算法是线性的,其复杂度为O(n),这是关于它的最重要的事实。这种表示法会清除46N之前放置的任何值,因为它无关紧要。

答案 1 :(得分:1)

  

哪种方法正确?大O值是相同的。但是,如果有人要求给出算法的步数,我该如何回答?

这是一个惯例问题:

  • 有些人将加法和乘法统计在一起,
  • 其他只是乘法,因为它们通常比添加更苛刻的操作(尽管在现代架构中不那么真实),并且
  • 还有其他保留单独的加法和乘法计数,

只要你清楚地知道你采用哪种惯例,任何事情都会发生。尽管它会影响常数因子,但约定的选择通常对渐近线(&#34; Big-O值&#34;)没有影响。 / p>

编辑:正如his comment中的dwn所指出的那样,接近金属&#34;由于编译器/解释器优化技巧,最终可能会出现与源代码不同的算法复杂性。