零基础学C语言(5):循环控制的应用案例
素数
只能被1和自己整除的数,不包括1, 如2,3,5,7,11,13,15,17,19…
#include <stdio.h>
int main()
{
int x;
scanf("%d",&x);
int i;
int isPrime = 1; //x是素数
for (i=2;i<x;i++){
if(x%i==0){
isPrime = 0;
break
}
}
if (isPrime == 1){
printf("是素数\n");
} else{
printf("不是素数\n");
}
return 0;
}
break:跳出循环
continue:跳过循环这一轮剩下的语句进入下一轮,可以使用断点-调试-下一步来看。
#include <stdio.h>
int main()
{
int x;
//scanf("%d",&x);
x=9;
int i;
int isPrime = 1; //x是素数
for (i=2;i<x;i++){
if(x%i==0){
isPrime = 0;
continue;
}
printf("%d\n",i);
}
if (isPrime == 1){
printf("是素数\n");
} else{
printf("不是素数\n");
}
return 0;
}
也可以不用isPrime变量,循环结束后,i=x就是素数,i<x就不是素数。但不可取,在没有显著提升程序运行效率的同时让程序变得不易理解。
输出100以内的素数
前面是给定一个数,判断是不是素数。现在需要输出100以内的所有素数。
嵌套的循环
#include <stdio.h>
int main()
{
int x;
//scanf("%d",&x);
for (x=2;x<100;x++)
{
int i;
int isPrime = 1; //x是素数
for (i=2;i<x;i++){
if(x%i==0){
isPrime = 0;
break;
}
}
if (isPrime == 1){
printf("%d ",x);
}
}
printf("\n");
return 0;
}
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
输出前50个素数
那么for循环就不合适了,只适用于次数或范围是确定值的。
需要计数器,找到一个素数就要记一个,只要计数器小于50,就要继续循环。
#include <stdio.h>
int main()
{
int x;
//scanf("%d",&x);
x = 2;
int cnt =0; //计数器
while (cnt<50)
//for (x=2;x<1000;x++)
{
int i;
int isPrime = 1; //x是素数
for (i=2;i<x;i++){
if(x%i==0){
isPrime = 0;
break;
}
}
if (isPrime == 1){
printf("%d ",x);
cnt ++; //找到素数计数器 +1
}
x++;
//for语句省略x++;
}
printf("\n");
return 0;
}
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199 211 223 227 229
多重循环
凑硬币
如何用1角、2角和5角的硬币凑出I0元以下的金额呢?——枚举
#include <stdio.h>
int main()
{
int x;
int one,two,five;
//scanf("%d",&x);
x = 2;
for (one = 1; one < x*10; one ++){
for (two =1; two < x*10/2; two ++){
for (five=1;five < x*10/5;five++){
if (one+two*2+five*5 == x*10){
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元
break和continue只能对它所在的那层循环做。
那如何跳出多重循环?
凑硬币题目中,就是给出一个答案就跳出循环。
法一:通过设置exit接力break
#include <stdio.h>
int main()
{
int x;
int one,two,five;
int exit = 0;
//scanf("%d",&x);
x = 2;
for (one = 1; one < x*10; one ++){
for (two =1; two < x*10/2; two ++){
for (five=1;five < x*10/5;five++){
if (one+two*2+five*5 == x*10){
printf("可以用%d个1角加%d个2角加%d个5角得到%d元\n",
one,two,five,x);
exit = 1;
break;
}
}
if (exit ==1 )break;
}
if(exit==1) break;
}
return 0;
}
可以用1个1角加2个2角加3个5角得到2元
法二: goto语句
使用gotoout语句,并设置要跳出的out地方。(建议只在最内层跳到最外层的时候使用)
#include <stdio.h>
int main()
{
int x;
int one,two,five;
//scanf("%d",&x);
x = 2;
for (one = 1; one < x*10; one ++){
for (two =1; two < x*10/2; two ++){
for (five=1;five < x*10/5;five++){
if (one+two*2+five*5 == x*10){
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元
循环应用
求和1+1/2+1/3+1/4+…+1/n.
起始值1,终点值n,均明确,所以用for循环是最好的。
#include <stdio.h>
int main()
{
int n;
int i;
double sum = 0.0;
scanf("%d",&n);
for (i=1; i<=n; i++){
sum+=1.0/i;
}
printf("f(%d)=%f\n",n,sum);
return 0;
}
10
f(10)=2.928968
求和1-1/2+1/3-1/4+…+1/n.
引入sign=1.0,再通过sign=-sign来翻转正负号。
#include <stdio.h>
int main()
{
int n;
int i;
double sum = 0.0;
//int sign=1;
double sign=1.0;
scanf("%d",&n);
for (i=1; i<=n; i++){
sum += sign/i;
sign = -sign;
}
printf("f(%d)=%f\n",n,sum);
return 0;
}
求最大公约数
输入两个数a和b,输出它们的最大公约数。
例:输入12和18,输出6。
法一:枚举法
法二:辗转相除法
1.如果b等于0,计算结束,a就是最大公约数;
2.否则,计算a除以b的余数,让a等于b,而b等于那个余数;
3.回到第一步。
#include <stdio.h>
int main()
{
int a,b;
int t;
scanf("%d %d",&a,&b);
while(b!=0){
t=a%b;
a=b;
b=t;
}
printf("gcd=%d\n",a);
return 0;
}
12和18的最大公约数是6.
12 18
gcd=6
正序分解整数
- 输入一个非负整数,正序输出它的每一位数字
- 输入:13425
- 输出:1,3,4,2,5
#include <stdio.h>
int main()
{
int x;
//scanf("%d",&x);
x = 13425;
do{
int d = x % 10;
printf("%d ",d);
x /= 10;
} while( x > 0 );
printf("\n");
return 0;
}
5 2 4 3 1
解决最后一位多个空格的问题
#include <stdio.h>
int main()
{
int x;
//scanf("%d",&x);
x = 13425;
do{
int d = x % 10;
printf("%d ",d);
if ( x >= 10) {
printf(" ");
}
x /= 10;
} while( x > 0 );
printf("\n");
return 0;
}
先循环得出逆整数,把x最右边那位加到t
#include <stdio.h>
int main()
{
int x;
//scanf("%d",&x);
x = 13425;
int t = 0;
do{
int d = x%10;
t = t*10+d;
x/=10;
} while(x>0);
printf("x=%d,t=%d\n",x,t);
x=t;
do{
int d = x % 10;
printf("%d ",d);
if ( x >= 10) {
printf(" ");
}
x /= 10;
} while( x > 0 );
printf("\n");
return 0;
}
x=0,t=52431
1 3 4 2 5
但这种做法,对于末尾有0的数字不行,例如700,会输出7而不是007。
x=0,t=7
7
回想前面三位数求逆序,最高位是用x/100得到的。
#include <stdio.h>
int main()
{
int x;
//scanf("%d",&x);
x = 13425;
int mask =10000;
do {
int d = x / mask;
printf("%d",d);
if (x>9){
printf(" ");
}
x%=mask;
mask /=10;
printf("x=%d,mask=%d,d=%d\n",x,mask,d);
}while(x>0);
printf("\n");
return 0;
}
输出
1 x=3425,mask=1000,d=1
3 x=425,mask=100,d=3
4 x=25,mask=10,d=4
2 x=5,mask=1,d=2
5 x=0,mask=0,d=5
输入70000怎么办?输出还是7!
第一轮x就等于0了,但mask还不是0,所以应该是mask为0。而且mask不应该是固定的,对于3位数应该是100,4位数应该是1000,所以要先计算整数的位数cnt然后用pow函数,也可以把mask从1开始乘10。
#include <stdio.h>
int main()
{
int x;
//scanf("%d",&x);
x = 100;
int mask = 1;
do{
x/=10;
mask *=10;
}while (x>9);
printf("mask=%d\n",mask);
do {
int d = x / mask;
printf("%d",d);
if (mask>9){
printf(" ");
}
x %= mask;
mask /=10;
}while(mask>0);
printf("\n");
return 0;
}
但也有问题,输入x=1的时候,我们希望我们的mask是1而不是10,因为我们用了do-while,个位数都乘了,所以换成while。
#include <stdio.h>
int main()
{
int x;
//scanf("%d",&x);
x = 1;
int mask = 1;
int t=x; //存放初始x,防止x变掉了。
while (x>9){
x/=10;
mask *=10;
}
printf("x=%d,mask=%d\n",mask);
do {
int d = x / mask;
printf("%d",d);
if (mask>9){
printf(" ");
}
x %= mask;
mask /=10;
}while(mask>0);
printf("\n");
return 0;
}
更多推荐
零基础学浙大翁恺C语言(5):循环控制
发布评论