Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 算法的大O符号_C++_Algorithm_Big O_Time Complexity_Analysis - Fatal编程技术网

C++ 算法的大O符号

C++ 算法的大O符号,c++,algorithm,big-o,time-complexity,analysis,C++,Algorithm,Big O,Time Complexity,Analysis,我正忙着做一项作业,我正努力回答一个问题。我知道我不应该直接问作业问题,所以如果我没有得到直接的答案,我会理解。但不管怎样,还是这样 我们必须计算不同算法的运行时复杂性,我一直坚持的是这个 for(int i = 1 ; i < n ; i++) for(int j = 0 ; j < i ; j +=2) sum++; 当我看这些结果时,O符号似乎应该比O(n)大得多 我们在作业中给出的4个选项是:O(1)、O(n2)、O(n)和O(logn)。正如我之前

我正忙着做一项作业,我正努力回答一个问题。我知道我不应该直接问作业问题,所以如果我没有得到直接的答案,我会理解。但不管怎样,还是这样

我们必须计算不同算法的运行时复杂性,我一直坚持的是这个

for(int i = 1 ; i < n ; i++)
    for(int j = 0 ; j < i ; j +=2)
        sum++;
当我看这些结果时,O符号似乎应该比O(n)大得多

我们在作业中给出的4个选项是:O(1)、O(n2)、O(n)和O(logn)。正如我之前所说,我看不出它怎么会像O(n2)那么大,但结果表明了这一点。所以我只是觉得我没有完全理解这一点,或者我缺少了一些联系


任何帮助都将不胜感激

从您的输出看来: 总和~=(n^2)/4

这显然是O(n^2)(实际上可以用teta替换O)。
您应该还记得Big-O表示法的定义。请参阅。

大O表示法不提供操作数。它只是告诉你,随着投入的增加,它将以多快的速度增长。这就是你观察到的

当您增加输入
c
次数时,操作总数将增加
c^2

如果您精确计算(几乎)精确的操作数,您将得到
(n^2)/4

当然,你可以用和来计算,但因为我不知道如何使用数学,所以我会给出一个“经验”解释。具有相同开始和结束条件的简单循环中的循环给出了
n^2
。这样的循环为
“i”
“j”
生成所有可能组合的矩阵。因此,在这两种情况下,如果开始是
1
,结束是
N
,则得到
N*N
组合(或有效的迭代)

但是,您的内部循环用于
i
。这基本上是把这个正方形变成一个三角形,这是第一个
0.5
因子,然后你跳过其他元素,这是另一个
0.5
因子;乘以1/4


O(0.25*n^2)=O(n^2)
。有时人们喜欢把这个因子留在这里,因为它可以让你比较两个复杂度相同的算法。但是它并没有改变相对于
n

的增长率,问题是这里的操作数取决于
n
的平方,即使总数小于n²。尽管如此,缩放对Big-O表示法至关重要,因此它是
O(n²)

记住Big-O是渐近表示法。常数(加法或乘法)对其没有影响

因此,外部循环运行
n次
,而在
i次
时,内部循环运行
i/2次。如果不是
/2
部分,它将是所有数字的总和
1。。n
,这是众所周知的
n*(n+1)/2
。对于非零的
a
,它扩展为
a*n^2+b*n+c
,因此它是
O(n^2)

我们不是对
n
数字求和,而是对
n/2
数字求和。但这仍然在
(n/2)*((n/2)+1)/2
附近。对于非零的
d
,它仍然扩展为
d*n^2+e*n+f
,因此它仍然是
O(n^2)

for (int i = 1 ; i < n ; i++)
    for (int j = 0 ; j < i ; j +=2)
        sum++;
因此,对于
n==2N
,我们有
(n/2)*(n/2+1)
~=
(n*n)/4


<> >代码> o(n)席/席>

你对时间复杂度的理解是不恰当的。时间复杂度不仅仅是“和”变量的问题。“和”只计算内环迭代次数的多少,而且还必须考虑外循环迭代的总数。

现在考虑你的程序:

 for(int i = 1 ; i < n ; i++)
    for(int j = 0 ; j < i ; j +=2)
        sum++;
for(int i=1;i
时间复杂度是指程序相对于输入值的运行时间(此处为n)。此处的运行时间并不表示在计算机中执行程序所需的实际时间。实际所需时间因机器而异。因此,要获得独立于机器的运行时间,大O表示法非常有用。Bog O实际上来自数学,它用数学函数来描述运行时间

外部循环总共执行(n-1)次。对于每个(n-1)值(从i=1开始),内部循环迭代i/2次。因此,内部循环迭代的总数=1+1+2+2+3+3+…+(n/2)+(n/2)=2(1+2+3+…+n/2)=2*(n/2(n/2+1))/2=n^2/4+n/2。
同样地,“和+ +”也执行了总共N ^ 2/4 +N/2次。现在考虑程序1行的成本=C1,行2的成本=C2和线3=C3的成本。因此,执行程序所需的总时间=c1*(n-1)+c2*(n^2/4+n/2)+c3*(n^2/4+n/2)=(c2+c3)n^2/4+(c2+c3)n/2+c1*n-c1。因此,所需时间可以用数学函数表示。在大O表示法中,可以说它是O((c2+c3)n^2/4+(c2+c3)n/2+c1*n-c1)。如果是大O表示法,低阶项和高阶项的系数可以忽略。因为对于n的大值,n^2比n大得多。所以你可以说它是O((c1+c2)n^2/4)。同样,对于n的任何值,n^2比(c1+c2)n^2/4大一个常数因子,所以你可以说它是O(n^2)。

“j变量是每个循环的两倍。”。我想你误读了
j*=2将加倍
j+=2
增加了2。是的,对不起,这是一个错误类型:)我现在将其编辑掉。它介于O(n)和O(n^2)之间,所以我认为它默认为较大的一个。提示:1+2+…+的和是什么N省略其他术语会如何影响这一点?@Chemistpp
3n*ln
也介于线性和二次之间,即使从技术上讲是在O(n^2)中,这也不是一个严格的界限(这是我们通常谈论的)。它在O(n log n)上。这里的“依赖”仅表示“与成比例”。实际数字还取决于
n
(对于某些c,通过函数f(x)=cx²),但i
0+2+4+6+...+2N == 2 * (0+1+2+3+...+N) == 2 * (N * (N+1) / 2) == N * (N+1)
 for(int i = 1 ; i < n ; i++)
    for(int j = 0 ; j < i ; j +=2)
        sum++;