一、引例 - 牛客网OJ题
为了更好地说明这个问题,我们以一道牛客网的题目作引例。题目链接贴在这里
题干如下
基本思路
这道问题的首先一步应该考虑到将输入数字的各个位数求出,并进行判定每位数字是奇数还是偶数
并根据奇偶性进行赋值,若为奇数,则赋值1;若为偶数,则赋值0;想到这里并不难,困难的是我们该如何将赋值后的数字符合题目要求地打印出来。今天让我们来分享一些在卧虎藏龙的牛客网中牛人的解题方法和解题思路。
二、范例
范例一
from 西西西西西西西
#include <stdio.h>
#include <math.h>
int main() {
int n = 0;
scanf("%d", &n);
int ret = 0;
int i = 0;
while (n) {//while(n)表示当n=0的时候循环停止
//相当于while(n!=0),因为当while循环为0时为fault,
//计算机默认当结果为fault时不进入循环
int num = n % 10;
if (0 == num % 2)
//判断num是否为偶数
num = 0;
else //因为一个数字不是奇数就是偶数,
//上面已经判断出来偶数的情况
/ /因此不必判断if(1==num%2)或者if(0!=num%2)
num == 1;
ret += num * pow(10, i++);
//每循环一次i++自增,
// 每一次循环除10,第i次循环就是除10^i,
//pow(10,i++)乘以10^n
n /= 10;
}
printf("%d", ret);
return 0;
}
以上便是大佬的代码,思路清晰严谨,那么请允许我化身一次高鹗,为这代码作注释。
友情提醒,我将原代码中的w换成num,因为w做变量相对不常见,换成num看代码的时候就不会
花精力思考w是代指什么,多花时间在反应上,从而提高理解代码的效率。
知识点
pow(x,y)函数
表示x的y次方的函数,头文件为<math.h>
完整形式是double pow(double x,double y)
可能导致错误的情况:
如果底数是负数并且指数不是整数,则会导致定义域错误(domain erorr)。
如果底数和指数都为零,则还可能导致定义域错误(domain erorr)。
如果底数为零且指数为负,则可能会导致定义域错误(domain erorr)或极点错误(pole error)(也可能没有,具体取决于库实现)。
如果结果太大或太小而无法用返回类型的值表示,该函数也可能会导致范围错误(range error)。
详情见
cplusplus.com/reference/cmath/pow/https://cplusplus.com/reference/cmath/pow/
范例二
from 1213812
#include <stdio.h>
int bian(long long n)
{
int b = n%10;//
int c = b%2;
n = n/10;
if( n )
return 10 * bian(n) +c;
return c;
}
int main()
{
long long n = 0;
scanf("%lld",&n);
int a = bian(n);
printf("%d",a);
return 0;
}
在下在这里不得不要佩服1213812大佬的思维,简直惊为天人,以 int c= b%2的方式巧妙地避免了用 if 语句判断奇偶性并赋值的过程,使代码更加简洁高效。
笔者认为,递归的难点在于一次次递归需要很强的想象力,因此笔者建议在考虑递归问题的时候在草稿纸上模拟递归进行,可以简化思考的难度,并更加深入的了解递归。
知识点
递归的两个必要条件
1)递归存在限制条件,当满足这个必要条件的时候,递归就不再继续。
2)每次递归调用之后,越来越接近这个条件。