在学习快速联合算法时,我遇到了这两个陈述
for(i=p; i!=id[i]; i=id[i]);
for(j=q; j!=id[j]; j=id[j]);
因为我只学习了循环就像是
for(i=0; i<100; i++)
我不知道两个陈述和以下陈述之间的区别
i=p; i=id[i];
j=q; j=id[j];
我不知道为什么结果会有所不同?
谢谢
我想问为什么
#include <stdio.h>
#define N 10000
int main()
{
int i, j, p, q, id[N];
for(i=0; i<N; i++) id[i]=i;
while(scanf("%d %d\n", &p, &q)==2)
{
for(i=p; i!=id[i]; i=id[i]);
for(j=q; j!=id[j]; j=id[j]);
if(i==j) continue;
id[i]=j;
printf(" %d %d\n", p, q);
}
}
与
不同#include <stdio.h>
#define N 10000
int main()
{
int i, j, p, q, id[N];
for(i=0; i<N; i++) id[i]=i;
while(scanf("%d %d\n", &p, &q)==2)
{
i=p; i=id[i];
j=q; j=id[j];
if(i==j) continue;
id[i]=j;
printf(" %d %d\n", p, q);
}
}
我测试了结果,这就是为什么我感到困惑
答案 0 :(得分:1)
i=p;
将i
设置为变量p
的值(在程序的其他位置定义和初始化)
i=id[i]
将i
设置为数组i
的{{1}}元素的值(在程序的其他位置定义和初始化)
id
循环将for(i=p; i!=id[i]; i=id[i]);
初始化为i
的值,如果p
不等于i
的值,则执行for循环内的语句一次数组i
,然后停止。
进一步解释:
假设变量有一些值:
id
输出:
执行循环!
然后是分段错误。
会发生什么:
我被设置为4,然后与id [4]进行比较。这是不相等的,因此循环被触发。之后它将i设置为5.现在它尝试将id [5]与i进行比较。这是不允许的,因为id只有5个元素的空间,索引从0开始。
答案 1 :(得分:0)
当看到像这样的“循环”非标准时,将for循环转换为while循环会有所帮助。 (这就是他们真正的所有)
要做到这一点,请记住for循环由分号分隔的三个部分组成。初始化部分,条件部分以及更新或增量部分:
for(initialize statement; boolean loop conditional; update/increment statement);
在循环之前执行initialize语句,计算循环条件以确定循环是否继续,并且更新/增量语句作为循环结束执行。
你的第一个例子:
for(i=p; i!=id[i]; i=id[i]);
作为一个while循环,看起来像..
i = p
while(i!=id[i]) {
i = id[i];
}
你的第二个例子:
for(j=q; j!=id[j]; j=id[j]);
作为一个while循环,看起来像..
j = q
while(j!=id[j]) {
j = id[j];
}
一旦这样写完,就会更容易分辨出发生了什么。
我们将循环变量初始化为两个值之一,p或q。
然后,我们在循环变量指定的位置查看数组“id”并用它更新循环变量。这具有在数组中查找下一个循环变量的效果。换句话说,数组中的每个槽都包含要跳转到的下一个值。
条件检查以查看目的地是否与当前位置相同。也就是说,如果我们被“告知”跳到我们已经在的位置。
两个循环之间的区别仅在于初始化值。第一个初始化为p,其中第二个初始化为q。
手动跳过诸如..的简单案例可能会有所帮助。
p=0
q=1
id = {1,2,2}
p=2
q=1
id = {0,0,2}