多重循环
输出100以内的素数
在之前判断一个数字是否为素数的程序基础上,在外面嵌套了一个for循环控制数字从2到100之间逐个判断是否为素数:
#include <stdio.h>
int main()
{
int a;
for(a = 2;a < 100;a++){
int i;
int isPrime = 1; //素数为1
for(i = 2;i < a;i++){
if(a % i == 0){
isPrime = 0;
break;
}
}
if(isPrime == 1){
printf("%d\n",a);
}
}
return 0;
}
2
3
...
89
97
--------------------------------
Process exited after 0.02239 seconds with return value 0
上述程序的6行有一个for循环,循环内的9行还有一个for循环,构成了一个两重循环。 循环的嵌套是指循环内包含一个或多个循环,循环的类型没有限制,可以是for、while等嵌套,不需特殊注意。 ::: tip 上述程序中第7、8行(主要是第8行)程序语句不能放在该for循环外,如果放在开头“int a;”后面,进入循环后,每一轮循环都没有了isPrime变量重置为1的步骤,一旦遇到合数,isPrime变量变为0后,后面无论是素数还是合数,15行的if条件均不满足,不再输出素数。 ::: ::: warning 为避免混淆,循环嵌套中的不同循环不能使用相同的变量。 :::
输出前50个素数
修改for循环:
#include <stdio.h>
int main()
{
int x;
int cut = 0;
for(x = 2;cut < 50;x++){
int i;
int isPrime = 1; //素数为1
for(i = 2;i < x;i++){
if(x % i == 0){
isPrime = 0;
break;
}
}
if(isPrime == 1){
printf("%d\n",i);
cut++;
}
}
return 0;
}
2
3
...
227
229
--------------------------------
Process exited after 0.02735 seconds with return value 0
使用while循环代替for循环:
#include <stdio.h>
int main()
{
int x = 2;
int cut = 0;
while(cut < 50){
int i;
int isPrime = 1; //素数为1
for(i = 2;i < x;i++){
if(x % i == 0){
isPrime = 0;
break;
}
}
if(isPrime == 1){
printf("%d\n",i);
cut++;
}
x++;
}
return 0;
}
2
3
...
227
229
--------------------------------
Process exited after 0.03031 seconds with return value 0
离开多重循环
凑钱数
使用一角两角五角的纸币凑够两元钱:
#include <stdio.h>
int main()
{
int x = 2; //x为金额
int one,two,five;
for(one = 1;one < x*10;one++){
for(two = 1;two < x*10/2;two++){
for(five = 1;five < x*10/5;five++){
if(x*10 == one + two*2 + five*5){
printf("需要使用%d个1角和%d个2角和%d个5角得到%d元\n",one,two,five,x);
}
}
}
}
return 0;
}
需要使用1个1角和2个2角和3个5角得到2元
需要使用1个1角和7个2角和1个5角得到2元
需要使用2个1角和4个2角和2个5角得到2元
需要使用3个1角和1个2角和3个5角得到2元
需要使用3个1角和6个2角和1个5角得到2元
需要使用4个1角和3个2角和2个5角得到2元
需要使用5个1角和5个2角和1个5角得到2元
需要使用6个1角和2个2角和2个5角得到2元
需要使用7个1角和4个2角和1个5角得到2元
需要使用8个1角和1个2角和2个5角得到2元
需要使用9个1角和3个2角和1个5角得到2元
需要使用11个1角和2个2角和1个5角得到2元
需要使用13个1角和1个2角和1个5角得到2元
--------------------------------
Process exited after 0.0138 seconds with return value 0
如果想要让程序在输出一种可行方案后终止跳出循环,需要使用break,如果在上述程序的printf后加上一个break语句,debug后可以看到,循环并没有完全跳出。 ::: tip break只能跳出它所在的那层循环。在多重循环中无法跳出所有的循环。 ::: 可以在每一层循环中都使用break语句跳出当前循环,但不是简单的添加break语句就可以实现,需要在当最内层循环break跳出后,外面的循环才会执行break。当xxxx条件满足时执行xxxx,需要添加一个变量exit。 方法一:接力break:
#include <stdio.h>
int main()
{
int x = 2; //x为金额
int one,two,five;
int exit = 0;
for(one = 1;one < x*10;one++){
for(two = 1;two < x*10/2;two++){
for(five = 1;five < x*10/5;five++){
if(x*10 == one + two*2 + five*5){
printf("需要使用%d个1角和%d个2角和%d个5角得到%d元\n",one,two,five,x);
exit = 1;
break;
}
}
if (exit){
break;
}
}
if(exit){
break;
}
}
return 0;
}
需要使用1个1角和2个2角和3个5角得到2元
--------------------------------
Process exited after 0.0177 seconds with return value 0
::: tip 上述程序中if(exit)相当于if(exit == 1),原因是if的判断表示只要表达式不是0就满足条件。 ::: 方法二:goto语句:
#include <stdio.h>
int main()
{
int x = 2; //x为金额
int one,two,five;
for(one = 1;one < x*10;one++){
for(two = 1;two < x*10/2;two++){
for(five = 1;five < x*10/5;five++){
if(x*10 == one + two*2 + five*5){
printf("需要使用%d个1角和%d个2角和%d个5角得到%d元\n",one,two,five,x);
goto out;
}
}
}
}
out:
return 0;
}
需要使用1个1角和2个2角和3个5角得到2元
--------------------------------
Process exited after 0.01486 seconds with return value 0
在需要离开整个循环的地方添加一个goto语句,goto后需要有一个标号,标号需要自己定义,标号以冒号结尾,表示从goto直接跳到标号所指的位置。 ::: danger 多重循环需要从最内侧直接跳出循环时可以使用goto语句。 其他场景下不要使用goto,goto的滥用会破坏程序的结构性。 :::