算法的大O符号
Big O Notation for Algorithm
我正忙于做作业,正在为一个问题而挣扎。我知道我不应该直截了当地问作业问题,所以如果我没有得到直接的答案,我会理解的。但不管怎样,还是来了。
我们必须计算不同算法的运行时复杂性,我一直坚持的是这个。
for(int i = 1 ; i < n ; i++)
for(int j = 0 ; j < i ; j +=2)
sum++;
现在,根据我的理解,我的第一个想法是小于O(n2),因为嵌套循环没有运行完整的n次,而且j变量在每个循环中递增2,而不是像循环的正常迭代那样迭代。尽管如此,当我用N=10、N=100、N=1000等进行一些代码模拟时,当我输出sum变量时,我得到了以下结果。
N = 10 : 25,
N = 100 : 2500,
N = 1000 : 250000,
N = 10000 : 25000000
当我看到这些结果时,O符号似乎应该比O(n)大得多。
我们在赋值中给出的4个选项是:O(1),O(n2)、O(n)和O(logn)。正如我之前所说,我看不出它怎么会像O(n2)那么大,但结果表明了这一点。所以我只是觉得我没有完全理解这一点,或者我错过了一些环节。
任何帮助都将不胜感激!
Big O表示法不会给出操作数。它只是告诉你,随着投入的增加,它将以多快的速度增长。这就是你观察到的。
将输入c
增加一倍后,操作总数将增加c^2
。
如果你精确地计算(几乎)精确的运算次数,你就会得到(n^2)/4
。
当然,你可以用总和来计算,但由于我不知道如何在SO上使用数学,我将给出一个"经验"解释。具有相同起始和结束条件的简单环中循环得到n^2
。这样的循环产生"i"
和"j"
的所有可能组合的矩阵。因此,如果开始是1
,结束是N
,在这两种情况下,您都可以得到N*N
组合(或有效的迭代)。
但是,您的内部循环适用于i < j
。这基本上是由这个正方形形成一个三角形,这是第一个0.5
因子,然后你跳过其他元素,这是另一个0.5
因子;乘以1/4。
和CCD_ 13。有时人们喜欢把这个因素留在那里,因为它可以让你比较两种具有相同复杂性的算法。但它不改变相对于CCD_ 14的生长比率。
请记住,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)
。
从您的输出中可以看到:sum~=(n^2)/4。
这显然是O(n^2)(实际上你可以用teta代替O)。您应该记得Big-O表示法的定义。看见http://en.wikipedia.org/wiki/Big_O_notation.
问题是,这里的运算次数取决于n
的平方,尽管总数小于n²。然而,缩放对于Big-O表示法来说很重要,因此它是O(n²)
使用:
for (int i = 1 ; i < n ; i++)
for (int j = 0 ; j < i ; j +=2)
sum++;
我们有:
0+2+4+6+...+2N == 2 * (0+1+2+3+...+N) == 2 * (N * (N+1) / 2) == N * (N+1)
因此,对于n == 2N
,我们有(n / 2) * (n / 2 + 1)
~=(n * n) / 4
所以O(n²)
您对时间复杂性的理解并不恰当。时间复杂性不仅仅是"answers"变量的问题sum只计算内部循环迭代的次数,但您还必须考虑外部循环迭代的总数。
现在考虑一下你的程序:
for(int i = 1 ; i < n ; i++)
for(int j = 0 ; j < i ; j +=2)
sum++;
时间复杂性是指程序相对于输入值的运行时间(此处为n)。此处的运行时间并不意味着在计算机中执行程序所需的实际时间。实际所需时间因机器而异。因此,要获得独立于机器的运行时间,大O表示法非常有用。Bog O实际上来自数学,它用数学函数来描述运行时间。
外循环总共执行(n-1)次。对于这些(n-1个)值中的每一个(从i=1开始),内循环迭代i/2次。所以内循环迭代的总数=1+1+2+2+3++(n/2)+(n/2)=2(1+2+3+…+n/2)=2*(n/2(n/2+1))/2=n^2/4+n/2。类似地,"sum++"也执行了总共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。在大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)。
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 有符号的int和int-有没有一种方法可以在C++中区分它们
- 基于ELO的团队匹配算法
- C++选择排序算法中的逻辑错误
- 将无符号char*转换为std::istream*C++
- 如何在C++中将一个无符号的 int 转换为两个无符号的短裤?
- 有没有办法将谓词中的元素偏移量传递给 std 算法?
- vscode g++链路故障:体系结构x86_64的未定义符号
- C++A*算法并不总是在路径中具有目标节点
- 排序算法c++
- 从矢量<无符号字符>转换为字符* 包括垃圾数据
- 如何理解将半精度指针转换为无符号长指针和相关的内存对齐
- Visual studio代码重构似乎不起作用(例如,重命名符号-f2)
- 使用gcc从静态链接的文件中查找可选符号
- 用于删除符号并生成排列的算法
- 用于在2个带符号整数区间之间进行除法的C++算法
- 指针算法符号
- 算法的大O符号
- 字符串匹配算法的大O符号