“拨”出数位上的数字 - 多种思路实现反向输出一个四位数(一)

简介: 本文介绍了编程中一个经典的入门题目——反向输出X位数,特别是以反向输出四位数为例,探讨了多种实现方法。这些方法包括使用取模运算分别获取数位、循环取数、利用scanf的宽度控制以及使用数组。每种方法都有其特点,适用于不同的场景。文章旨在帮助初学者拓宽编程思路,并鼓励读者讨论和分享更多实现方式。

前言


“反向输出一个X位数”是C语言乃至其它编程语言入门的一道经典例题。虽然难度不大,但其实现思路是多样的(共同的核心是如何拨出数位上的数字,并重新组合)。


对于初学者的学习而言,编程思路和代码实现自然是多多益善。并且,该编程问题容易作为一个思路模块出现在更大更复杂的编程项目中。因而,本文以“反向输出一个4位数为例”,整理了容易接触到的一些如何“拨出各个数位上的数字”的几种方法,而各个实现方法的利弊交给诸位读者自行理解与权衡,同时在最后添加了一道相对复杂的变式拓展习题。


希望对诸位读者学习C语言有所帮助。若诸位读者有更好的实现办法,非常欢迎各位指出讨论!


一、引例 -- 反向输出一个四位数

1. 题干描述



牛客网OJ题链接:


https://www.nowcoder.com/practice/1f7c1d67446e4361bf4af67c08e0b8b0?tpId=107&&tqId=33300&rp=1&ru=/ta/beginner-programmers&qru=/ta/beginner-programmers/question-ranking


2. 思路简述


总体思路非常简单:反向输出一个四位数,可以理解为将该四位数的个、十、百、千四个数位上的数字取出,并以相反的顺序重新组合。


如 1234,取出个位数4,十位数3,百位数2,千位数1,反向按千,百,十,个的顺序重组,即为4321.


二、实现思路 -- 拨出数字


思路一:用取模运算分别拨出数位


代码


//方法一
#include<stdio.h>
 
int main(){
    int num = 0;
    int ge,shi,bai,qian;    //分别接受各个数位上的数字
 
    scanf("%d",&num);    //输入一个四位数
 
    ge = num/1%10;
    shi = num/10%10;
    bai = num/100%10;
    qian = num/1000%10;
 
    printf("%d%d%d%d",ge,shi,bai,qian);
    
    return 0;
}


说明


拨出数位上的数字的常用方法:num/数位%10


例如,要取千位上的数字,则num/1000%10;要取百位上的数字,则num/100%10。以此类推,可以分别取出所有数位上的数字。


该方法的好处是,在取出数字后可以最灵活简便地进行组合。毕竟单个数字已经拿到手了,具体怎么排列(如不要反向输出,而要输出3124,4231等),完全可以任意。并且可以拿数位上的数进行任意的运算,以达到题干的某些要求。


例如经典例题水仙花数,水仙花数指的是一个三位数,个位³+十位³+百位³ = 这个数本身。那么完全可以用上述办法实现:



//示例-水仙花数
 
ge = num/1%10;
shi = num/10%10;
bai = num/100%10;
 
//达到如下条件的数称之为水仙花数:
ge*ge*ge + shi*shi*shi + bai*bai*bai == num


是一种非常容易想到的思路。


当然,这种方法不适合数量级比较大的情况。要是不止是四位数,更有五位数、六位数,显然这种方法就太麻烦了。


思路二:循环取数


代码


//方法二
 
int main(){
    int num = 0;
    scanf("%d",&num);
    while(num){
        printf("%d",num % 10);
        num /= 10;
    }
 
    return 0;
}


说明


这个思路与上一个比起来,看着令人舒服地多。它依然用到取模运算,但与思路一略有差别。它的实现流程是:


1. 模运算从低位到高位取出各位上的数字,并打印。


2. 除运算降低数位。


如此循环往复。以1234为例:


1234 % 10  得到个位上数字 4,由于它先被取出来打印,所以它最后也排在最前面。


1234 / 10  得到数位比之前低一位的新数 123  (其实也不难理解,我的目的就是把数位上的数取下来,既然个位数字4已经被我拿到了,那还留着4干什么?除运算把它扔掉了!)


这个思路还是比较巧妙的。虽然它的时间复杂度为O(N),但它确实比思路一更适合数位更多的情况。三位数、五位数、七位数的逆向它都能实现,而不需要再开辟新的变量。


思路三:scanf -- "%1d"

代码


//方法三
#include<stdio.h>
 
int main(){
    int a,b,c,d;
    scanf("%1d%1d%1d%1d",&a,&b,&c,&d);
    printf("%d%d%d%d",d,c,b,a);
 
    return 0;
}


说明



采取控制宽域输入的办法,直接取数,简单粗暴。该程序的实现原理如下:


"%*d"  可以理解为scanf从左向右一次性读入输入数的宽度(或从缓存区一次性取走的数字的个数),"%1d"即从左到右一次读入1个数字。



当输入1234 时,该程序的执行流程是这样的:


1给a        a = 1


2给b        b = 2


3给c        c = 3


4给d        d = 4


输出 d c b a,即 4321


当然,"%2d"则表示从左到右一次性读入两个。下图中,12给a,34给b



思路四:数组


代码


//方法四
#include<stdio.h>
 
int main()
{
    char ch[10];
    scanf("%s", ch);
    for (int i = 3; i >=0; i--)
    {
        printf("%c", ch[i]);
    }
    return 0;
}


说明

数组的办法也非常容易想到。采取数组的倒序遍历,可以直观地将四位数逆向输出,不需要特别地去“取数”。


“拨”出数位上的数字 - 多种思路实现反向输出一个四位数(二) + https://developer.aliyun.com/article/1518249?spm=a2c6h.13148508.setting.19.16ee4f0ewLnn61

相关文章
|
6月前
|
C++
“拨”出数位上的数字 - 多种思路实现反向输出一个四位数(二)
```markdown 编写函数,统计正整数中零的个数和最大数字。例如:1080有2个零,最大数字是8。主函数负责输入正整数。解题思路:通过循环取数,逐位检查,更新零的计数器和最大数字。示例代码使用C++实现,通过传址调用来改变主函数中的值。注意,循环遍历数位体现了对每个数位的处理思想。 ```
63 0
|
算法 测试技术
算法强化每日一题--字符串中找出连续最长的数字串
算法强化每日一题--字符串中找出连续最长的数字串
|
算法 C语言
【基础算法】浅浅刷个小题 # 移动零 # 丢失的数字 # 转换成小写字母 # 和为零的N个不同整数 # 猜数字 #
【基础算法】浅浅刷个小题 # 移动零 # 丢失的数字 # 转换成小写字母 # 和为零的N个不同整数 # 猜数字 #
|
人工智能 图计算
LeetCode--缺失的第一个正数(41)和 接雨水(42)
LeetCode--缺失的第一个正数(41)和 接雨水(42)
66 0
每日三题-电话号码的字母组合、字母异位词分组、找到所有数组中消失的数字
每日三题 电话号码的字母组合 字母异位词分组 找到所有数组中消失的数字
109 4
每日三题-电话号码的字母组合、字母异位词分组、找到所有数组中消失的数字
|
存储 算法
【题型总结】找到第n个自定义数 | 丑数系列 + 神奇数字
思路:对于对于任意一个丑数 x,其与任意的质因数(2、3、5)相乘,结果(2x、3x、5x)仍为丑数。因此可以使用优先队列(小根堆)存放丑数x,每次从队列取出最小值x,并将x所对应的2x、3x和5x入队。第n次出队的值即为第n个丑数
255 0
【题型总结】找到第n个自定义数 | 丑数系列 + 神奇数字
|
索引
力扣刷题记录——748. 最短补全词、744. 寻找比目标字母大的最小字母、747. 至少是其他数字两倍的最大数
力扣刷题记录——748. 最短补全词、744. 寻找比目标字母大的最小字母、747. 至少是其他数字两倍的最大数
131 0
力扣刷题记录——748. 最短补全词、744. 寻找比目标字母大的最小字母、747. 至少是其他数字两倍的最大数
|
索引
力扣刷题记录——434. 字符串中的单词数、448. 找到所有数组中消失的数字、455. 分发饼干
力扣刷题记录——434. 字符串中的单词数、448. 找到所有数组中消失的数字、455. 分发饼干
120 0
力扣刷题记录——434. 字符串中的单词数、448. 找到所有数组中消失的数字、455. 分发饼干