第4章 循环及其应用

4.1 循环控制及其应用

4.1.1 循环控制

找到从2到100的素数

  • int i, j, num = 0, n=0;
    for(i=2;i<=100;i++) {
        for(j=1;j<=i;j++) {
            if(i%j==0) {
                num++;
            }
        }
        if(num==2) {
            printf("%d ", i);
            n++;
        } else {
            num = 0;
        }
        num = 0;
    }
    printf("有%d个素数", n);
    
  • 素数是只能被1和自己整除的数,不包括1

判断一个数是不是素数

  • int x, i, isPremer = 1;
    scanf("%d", &x);
    for(i=2;i<x;i++) {
        if(x%i==0) {
            isPremer = 0;
            break;
        }
    } 
    if(isPremer) {
        printf("%d是素数", x);
    } else {
        printf("%d不是素数", x);
    }
    

break vs continue

21
  • break:跳出循环
  • continue:跳过循环这一轮剩下的语句进入下一轮

另一个版本的求素数:但不推荐这样做

int x, i;
scanf("%d", &x);
for(i=2;i<x;i++) {
    if(x%i==0) {
        break;
    }
} 
if(i<x) {
    printf("%d不是素数", x);
} else {
    printf("%d是素数", x);
}

4.2 嵌套的循环

4.2.1 循环的嵌套与跳出循环

找到从2到100的素数

int i, j, isPrime = 1, n=0;
for(i=2;i<=100;i++) {
    for(j=2;j<i;j++) {
        if(i%j==0) {
            isPrime = 0;
            break;
        }
    }
    if(isPrime) {
        printf("%d ", i);
        n++;
    } else {
        isPrime = 1;
    }    
}
printf("有%d个素数", n);

求素数算法总结

  • 第一种:遍历1~n的数,用它们除以,记录能整除的次数有多少,如果是2,那么就是素数,否则就不是素数
  • 第二种:不除1,不除n,但只要在2~n-1这个范围里面发现它能整除另一个整数,那么就不是素数
  • 第二种方法节省时间

嵌套的循环

  • 在循环里面还有循环

凑硬币(跳出多层循环)

  • 用1角,2角,5角凑出10元以下

  • int x, one, two, five, n, times=1;
    scanf("%d", &x);
    n=x*10;
    for(one = 1; one<n/1;one++) {
        for(two = 1; two<n/2;two++) {
            for(five = 1; five<n/5;five++) {
                if(five*5 + one*1 + two*2 == n) {
                    printf("%d、%d张1角 + %d张2角 + %d张5角 可以凑出%d元\n", times, one, two, five, x);
                    times++;
                }
            }
        }
    }
    
  • 但这样的话,我们会得到很多结果,但我们只需要一个就够了,那怎么办呢?

    • 用break?

      • 行不通,还是那么多结果,所以我们可以知道,break和continue只能对它所在的那层循环做,而做不到所有循环

      • 我们就有了第二种方法,给每层都加个break

        int x, one, two, five, n, times=1;
        scanf("%d", &x);
        n=x*10;
        for(one = 1; one<n/1;one++) {
            for(two = 1; two<n/2;two++) {
                for(five = 1; five<n/5;five++) {
                    if(five*5 + one*1 + two*2 == n) {
                        printf("%d、%d张1角 + %d张2角 + %d张5角 可以凑出%d元\n", times, one, two, five, x);
                        times++;
                        break;
                    }
                }
                break;
            }
            break;
        }
        
        • 但也是行不通,那么它每层都会break

那么我们就有另一条思路:判断,if语句

接力break

int x, one, two, five, n, exit=0;
scanf("%d", &x);
n=x*10;
for(one = 1; one<n/1;one++) {
    for(two = 1; two<n/2;two++) {
        for(five = 1; five<n/5;five++) {
            if(five*5 + one*1 + two*2 == n) {
                printf("%d张1角 + %d张2角 + %d张5角 可以凑出%d元\n", one, two, five, x);
                exit = 1;
                break;
            }
        }
        if(exit)break;
    }
    if(exit)break;
}

goto语句

int x, one, two, five, n;
scanf("%d", &x);
n=x*10;
for(one = 1; one<n/1;one++) {
    for(two = 1; two<n/2;two++) {
        for(five = 1; five<n/5;five++) {
            if(five*5 + one*1 + two*2 == n) {
                printf("%d张1角 + %d张2角 + %d张5角 可以凑出%d元\n", one, two, five, x);
                goto out;
            }
        }
    }
}
out:
  • go to的原理是:设置一个标号,这个标号就放在你想要go to跳到的地方
  • go to在历史上是有不好的,会破坏程序的结构性,所以很多人不会推荐去用go to
  • 但在某种场合下,还是可以使用的,比如需要从多层循环中跳到最外层

4.3 案例

4.3.1 前n项求和

22
int i, n;
double sum = 0.0;
scanf("%d", &n);
for(i=1;i<=n;i++) {
    sum += 1.0/i;
}
printf("%f", sum);
23

算法一

int i, n;
double sum = 0.0;
scanf("%d", &n);
for(i=1;i<=n;i++) {
    if(i&1) {
        sum += 1.0/i;
    } else {
        sum -=1.0/i;
    }
}
printf("%f", sum);

算法二

int i, n;
double sum = 0.0, sign = 1.0;
scanf("%d", &n);
for(i=1;i<=n;i++) {
    sum+=sign/i;
    sign = -sign;
}
printf("%f", sum);

算法三

int i, n;
double sum = 0.0, sign = 1;
scanf("%d", &n);
for(i=1;i<=n;i++) {
    sum+=sign*1.0/i;
    sign = -sign;
}
printf("%f", sum);

易错点

int main() {
	int n=0, i = 1;
	double sum = 0;
	scanf("%d", &n);
	for(;i<=n;i++) {
		sum += 1.0/i;//这里的1一定要是个浮点数
	}
	printf("%f", sum);
}

4.3.2 求最大公约数

输入两个数a和b,输出它们的最大公约数

  • 输入:12 18
  • 输出:6

算法一

int t, n1, n2;
printf("第一个数字:");
scanf("%d", &n1);
printf("第二个数字:");
scanf("%d", &n2);
while(n2>0) {
    t=n2;
    n2=n1%n2;
    n1=t;
}
printf("%d", t);

算法二

int

4.3.3 整数分解

反转整数

int a, t;
	
a=1234560;

while(a!=0) {
    printf("%d ",a%10);
    a=a/10;
}
	int x, t, i;
	
	x=1234560;
	t = x;
	int b, arr=0;
	while(t>0) {
		b=t%10;
		t=t/10;
		arr=arr*10+b;
	}
	
	printf("%d\n", arr);
	
	while(arr!=0) {
		printf("%d ",arr%10);
		arr=arr/10;
	}

我们有两种算法解决这个问题

  • 一,先算出位数,再求解
  • 二,先把需要求得数进行反转,再求解
int x, mask=1, t;
t=x;
while(t>0) {
    t%10;
    mask*=10;
}

while(x!=0) {
    printf("%d ",x%mask);
    x=x/10;
    mask/=10;
}
赞赏