[编程题]11、水仙花数

目录

前言:

1、题目展示:

2、问题分析:

一、首先是代码框架

二、main函数内的核心内容分析

3、最终代码展示:


前言:

开新专栏了,讲解100道基础语法编程题

用c语言讲解

目的是复习c语言中的基础语法,为单片机中的c语言代码分析做铺垫

专栏链接:

c语言基础语法编程题_1zero10的博客-优快云博客

1、题目展示:

 

2、问题分析:

此题是理解变量定义的位置,即明确其作用域以及循环与循环之间的逻辑的经典案例

因此主要从这两个方面进行讲解,顺带对代码的执行逻辑进行分析

采用先展示最终代码,再一步一步分析的思路

以下是完整的代码

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {
        int m, n;
        while (scanf("%d %d", &m, &n) == 2) {
                int first = 1;
                int found = 0;
                for (int i = m;i <= n;++i) {
                        int a = i / 100;//百位
                        int b = (i / 10) % 10;//十位
                        int c = i % 10;//个位
                        if (i == (a * a * a) + (b * b * b) + (c * c * c)) {
                                if (!first)printf(" ");
                                printf("%d", i);
                                first = 0;
                                found = 1;
                        }
                }
                if (!found)printf("no");
                printf("\n");
        }
        return 0;
}

 接下来我们来一步一步分析

一、首先是代码框架

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {

        return 0;
}

1、写上头文件 #include <stdio.h> 便于下面调用标准输入输出头文件内包含的内容

比如scanf printf...

2、因为一会儿要调用c语言不安全函数scanf,因此要加上#define _CRT_SECURE_NO_WARNINGS,防止报错

3、写上主函数main的框架

int main() {

return 0;

}

二、main函数内的核心内容分析

 int m, n;
        while (scanf("%d %d", &m, &n) == 2) {
                int first = 1;
                int found = 0;
                for (int i = m;i <= n;++i) {
                        int a = i / 100;//百位
                        int b = (i / 10) % 10;//十位
                        int c = i % 10;//个位
                        if (i == (a * a * a) + (b * b * b) + (c * c * c)) {
                                if (!first)printf(" ");
                                printf("%d", i);
                                first = 0;
                                found = 1;
                        }
                }
                if (!found)printf("no");
                printf("\n");
        }

首先从外层来看是顺序结构

1、先定义了两个整型输入变量m,n,为下面的多组输入做铺垫

2、搭好多组输入的代码框架,所有的程序的动作都会在里面,每一次两个数输入m,n,就执行while语句内的代码

while (scanf("%d %d", &m, &n) == 2) {

}

3、while语句内的代码核心就是要

3-1、在[m,n]这个区间内,遍历所有的数,判断每个数是不是水仙花数

3-2、遍历完所有数之后,如果有水仙花数,则输出所有的水仙花数,并且换行,让下一组输出是在另一行

3-3、如果没有水仙花数,则输出no,并且换行,让下一组输出是在另一行

4、所以我们的代码逻辑是这样的

我们先在while语句内第一行定义两个标签

4-1、int first = 1;

4-2、int found = 0;

(first和found在while循环内的原因是

1、first和found是在每组输入m,n之后进行相关功能而定义的数而非是无论while语句输入什么数,都恒定不变的数

2、如果定义在while语句外面,那么无论你每组输入的m,n是多少,first都恒为1,found都恒为0,显然不满足我们的要求)

先来看4-1、

因为每个水仙花数后面都跟着空格,再接着下一个水仙花数,所以要用到first

如果单纯

if (i == (a * a * a) + (b * b * b) + (c * c * c)) {

printf("%d", i);

printf(" ");

}

那么假设当i是你给出[m,n]范围内的最后一个水仙花数,后面没有水仙花数了,但是依然输出一个空格而题目要求的是如果是最后一个数了,就没有空格之间换行准备输入下一组数据了

那么first是怎么实现这一功能的

我们按第一次输入m,n并且遍历到第一个数开始举例

在第3行定义first=1

然后第5行 for语句开始遍历[m,n]区间内的所有数,并判断是否为水仙花数

如果当前数i的百位a,十位b,个位c都满足i==(a * a * a) + (b * b * b) + (c * c * c)

则执行第9行if语句内10、11、12、13行的内容

既然满足第9行if语句说明是当前数i水仙花数,因为第一次进行for循环,first的值还为初始值1,

所以 if (!first)后面的输出空格不执行 也就是题目要求的每组水仙花数的第一个数之前不能有空格

然后输出完当前第一个水仙花数i之后,在把first赋值为0,下一次如果第二个数是水仙花数的话,那么由于顺序结构,先执行10行,再执行11行,第一个水仙花数和第二个水仙花数之间就有了空格

再看4-2 found是如何实现功能的

第4行,定义int found = 0;表示找到了0个水仙花数

我们依然是按第一次输入m,n并且遍历到第一个数开始举例

第4行执行完了,开始执行第5行for循环,遍历[m,n]区间内的所有数,当前遍历的第一个数是i

然后i的如果当前数i的百位a,十位b,个位c都满足i==(a * a * a) + (b * b * b) + (c * c * c)

则执行第9行if语句内10、11、12、13、14行的内容

你会发现只要是[m,n]区间内存在水仙花数,都会从第5行走到第14行,found的值都从0变成了1

也就是说遍历完所有[m,n]区间内的数之后,如果没有水仙花数,那么found还是0

那么执行第16行,!found=1,输出no,然后执行第17行输出换行,然后再返回while循环的条件判断语句,输入m,n进行下一组的判断

遍历的过程中遇到水仙花数,执行3-14行的内容,之后found=1,再回到第5行进行下一个数是否为水仙花数的判断,直至遍历完所有数,然后行第16行,!found=0,不输出no,然后执行第17行输出换行,然后再返回while循环的条件判断语句,输入m,n进行下一组的判断

总结一下

1、变量定义写在哪儿的问题

第1行 定义m,n,开辟内存空间,是为了第二行while语句scanf输入能够把数据输入进来,并且存到内存里

第3、4行在while语句内定义first与found是为了每一次输入新的一组数据,水仙花数的判断逻辑以及空格输出逻辑不变,若first和found定义的位置不对,可能出现判断逻辑出错的情况

2、循环嵌套逻辑

while是大框架 对每组输入数据的操作都在while语句内实现

for循环+if(i == (a * a * a) + (b * b * b) + (c * c * c))是为了判断是否为水仙花数

for循环遍历每一个数,对遍历到的每个数执行if(i == (a * a * a) + (b * b * b) + (c * c * c))判断,因此

if(i == (a * a * a) + (b * b * b) + (c * c * c))写在for循环内

if (!found)printf("no");写在for循环外,表示遍历完所有数之后,再进行判断,如果遍历过程中存在水仙花数,那么found都会变成1,no无法输出,直至下一次输入m,n,found的值才进行重置成0的操作

3、最终代码展示:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {
        int m, n;
        while (scanf("%d %d", &m, &n) == 2) {
                int first = 1;
                int found = 0;
                for (int i = m;i <= n;++i) {
                        int a = i / 100;//百位
                        int b = (i / 10) % 10;//十位
                        int c = i % 10;//个位
                        if (i == (a * a * a) + (b * b * b) + (c * c * c)) {
                                if (!first)printf(" ");
                                printf("%d", i);
                                first = 0;
                                found = 1;
                        }
                }
                if (!found)printf("no");
                printf("\n");
        }
        return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值