好的,所以当我的教授在课堂上讨论时,它看起来很简单,但是当我完成作业时,我感到很困惑。这是一个功课的例子。
for (int i = 0; i < n; i++) // I know this runs at T(n)
for (int j = n - 1; j >= i; j--)
cout << i << " " << j << endl;
这是我理解的一个例子
for(int i=0; i<n-1; i++) {
for(int j=i+1; j<n; j++) {
1 Simple statement
}
对于那个例子,我只插入0,1和2.对于0,它运行n-1,1为n-2和2 n-3。所以我认为,对于作业示例,如果我插入0,它将运行n + 1,因为j必须大于或等于i,即0.如果它不明显,我很漂亮困惑。如果有人能告诉我如何解决它,那就是我的一天。谢谢你们。
答案 0 :(得分:0)
让我们深入了解功能。我们来挑选一些数字。
说,n = 5
所以我们的代码看起来像这样(神奇的伪代码使用INCLUSIVE循环,而不是它太重要了)
(1)for i = 0 to 4
(2)for j = 4 to i
(3)print i j
next
next
所以这是一个偏好问题,但通常假设循环每次执行需要花费1个简单语句(比较和增量)。因此,我们假设语句(1)和(2)的成本为2.语句(3)的成本为1.
现在确定T(n)。
我们的外循环for i = 0 to 4
正好运行n次。
我们的内循环for j = 4 to i
。 。 。我们会在那里挖一分钟。
对于n = 5的示例,循环(2)将执行如此
j = 4; i = 0; j = 4; i = 1; j = 4; i = 2; j = 4; i = 3 j = 4; i = 4;
j = 3; i = 0; j = 3; i = 1; j = 3; i = 2; j = 3; i = 3;
j = 2; i = 0; j = 2; i = 1; j = 2; i = 2;
j = 1; i = 0; j = 1; i = 1;
j = 0; i = 0;
因此它形成了这种金字塔形状,每次我们减少1次迭代。这个特殊的例子运行了5 + 4 + 3 + 2 + 1 = 15次。
我们可以将其写为SUM(i; i = 0到n)。
我们从precalc得知:=(1/2)(n)(n + 1)。
并且(3)将执行与内循环完全相同的次数,因为它是唯一的语句。所以我们的总运行时间将是。 。 。 成本(1)+成本(2)+成本(3) (2)(n)+ 2(1/2)(n)(n + 1)+(1/2)(n)(n + 1)
我们可以清理它
(3/2)(n)(n + 1)+ 2n = T(n)。
也就是说,这假设循环成本为2,语句成本为1.通常说循环成本为0且语句成本为1更有意义。如果是这种情况,则T(n)=(1 / 2)(N)(N + 1)。
并且认为T(n),我们知道T(n)是O(n ^ 2)。
希望这有帮助!
答案 1 :(得分:0)
这并不难。
单循环的3个示例:
for (int i = 0; i < n; i++)
for(int i = 0; i < n-1; i++)
for(int i = 2; i < n-1; i++)
第一个循环执行内容n
次(i=0,1,2,3,...,n-1
)
同样,第二个循环只有n-1
次
第三个是n-3
因为它不是0,而是2
(如果n
小于3,即n-3<0
,则根本不会执行)
在像
这样的嵌套循环中for(int i = 0; i < n-1; i++) {
for(int j = 0; j < n; j++) {
//something
}
}
对于外循环的每次传递,执行整个内循环,即。你可以将两个单循环计数相乘,以获得总共执行“某事”的频率。这是(n-1) * n = n^2 - n
。
如果内部循环依赖于外部循环的值,则会变得更复杂:
for(int i = 0; i < n-1; i++) {
for(int j = i+1; j < n; j++) {
//something
}
}
单独的内循环是n - (i+1)
次,外循环n-1
次(我从0变为n-2
)。
虽然有“正确”的方法来计算这一点,但有点逻辑思维通常更容易,正如你已经做过的那样:
i-value => inner-loop-time
0 => n-1
1 => n-2
...
n-2 => n - (n-2+1) = 1
所以你需要总和1+2+3+...+(n-1)
为了计算从1到x的和,以下公式有助于:
sum[1...x] = x*(x+1)/2
因此,从1到n-1
的总和是
sum[1...n-1] = (n-1)*(n-1+1)/2 = (n^2 - n)/2
这就是上面循环的解决方案(你的第二个代码)。
关于第一个代码:
外循环:n
内循环:从n-1
到i
包含,或从i到<=n-1
的其他方式,
或者从i
到<n
,n-i
次
i >= innerloop
0 n
1 n-1
2 n-2
...
n-1 1
...而且从1到n的总和是(n^2 + n)/2
。
答案 2 :(得分:-3)
调查问题的一种简单方法是对其进行建模并查看结果数据。
在你的情况下,问题是:内循环的迭代次数取决于外循环变量的值?
let n = 10 in [0..n-1] |> List.map (fun x -> x,n-1-x);;
上面的1行是显示发生情况的模型。如果您现在查看结果输出,您会很快注意到某些内容......
你注意到了什么?对于给定的N,你运行外循环N次 - 这是微不足道的。现在我们需要总结第二个数字,我们有解决方案:val it:(int * int)list = [(0,9); (1,8); (2,7); (3,6); (4,5); (5,4); (6,3); (7,2); (8,1); (9,0)]
sum(N-1..0) = sum(N-1..1) = N * (N-1) / 2
因此cout
次来电的总数是N *(N-1)/ 2。
另一种实现相同目的的简单方法是稍微修改一下你的功能:
int count(int n) {
int c = 0;
<outer for loop>
<inner for loop>
c++;
return c;
}