6-7 整数逆序输出 (100 分)
请写出将一个整数逆序输出的函数。
注意:此题要求递归求解且不允许使用数组。如果违反要求则没有分。
函数接口定义:
函数接口如下:
void reverse(int n) ;
其中 n
是用户传入的参数。 n
的值大于0且不超过int
的范围; 函数的返回值为空,其功能是逆序输出 n
。测试用例保证输入的n
末尾不为0。
裁判测试程序样例:
函数被调用进行测试的例子如下:
#include <stdio.h>
void reverse(int n) ;
int main()
{
int n;
scanf("%d",&n);
reverse(n) ;
printf("\n");
return 0;
}
/* 请在这里填写答案 */
输入样例:
1234
思路:
递归有两个关键:
1.递归式
2.递归边界
这里逆序输出,递归式可以想成 输出一个数+调用自己输出下一个数
边界就是n==0时结束
代码:
void reverse(int n){
printf("%d",n%10);
if((n=n/10)!=0){
reverse(n);
}
}
6-8 实验6_4_二进制转十进制 (100 分)
设计递归函数int convert(int n);用于将二进制数n转换为十进制数并返回。 递归函数设计思路与提示: 如将1101转换为十进制的形式:
1101=1 * 20 + 0 * 21 + 1 * 22 + 1 * 23 = 1101 % 10 + convert(110) * 2 ;
110 = 0 * 20 + 1 * 21 + 1 * 22 = 110 % 10 + convert(11) * 2;
11 = 1 * 20 + 1 * 21 = 11 % 10 + convert(1) * 2 ;
convert(1) = 1 ;
所以得到以下结论:当n==0或n==1时,函数返回n,否则返回n%10+convert(n/10)*2 。
输入与输出要求: 输入一个整数n,代表二进制数,其长度不大于10。输出转换后的十进制数,占一行。
函数接口定义:
函数原型如下:
int convert(int n);
其中 n
是用户传入的参数。 n
的长度不大于10;函数的返回值为转换后的十进制数。
裁判测试程序样例:
函数被调用的例子如下:
#include<stdio.h>
int convert(int n);
int main()
{
int n ;
scanf("%d",&n);
printf("%d\n",convert(n)) ;
return 0 ;
}
/* 请在这里填写答案 */
输入样例:
101010
输出样例:
42
思路:
递推式:ans=n%10+convert(n/10)*2
边界:n==0
代码:
int convert(int n){
int ans=0;
if(n)
ans=n%10+convert(n/10)*2;
return ans;
}
6-9 实验6_5_二进制的位数 (100 分)
设计递归函数int countBinary(int n); 用于将非负十进制整数n转换成二进制形式,并返回该二进制数的位数。如十进制数13的二进制形式为1101,位数为4,那么调用countBinary(13)的结果为4。
要求同学们先写出该问题的递归定义式,再设计递归函数。
输入与输出要求: 输入一个非负整数n。输出求得的结果,如输入“13”,输出“4”,占一行。
函数接口定义:
函数原型如下:
int countBinary(int n);
其中 n
是用户传入的参数。 n
的值不超过int
的范围。函数的返回值为 n
的二进制形式的位数。
裁判测试程序样例:
函数被调用的例子如下:
#include<stdio.h>
int countBinary(int);
int main()
{
int n;
scanf("%d",&n);
printf("%d\n",countBinary(n));
return 0 ;
}
/* 请在这里填写答案 */
输入样例:
13
输出样例:
4
思路:
十进制转二进制:除基取余法
递推式:z[num++]=n%2;
n=n/2;
countBinary(n);
边界:n==0
代码:
做一个既能输出二进制又能输出位数的函数
#include<stdio.h>
int countBinary(int n){
static int num=-1;
static int z[40]={0};
static int i=0;
num++;
z[num]=n%2;
if(n!=0){
countBinary(n/2);
}
else
for(i=num-1;i>=0;i--){
printf("%d ",z[i]);
}
return num;
}
int main()
{
int n=0;
int num=0;
scanf("%d",&n);
num=countBinary(n);
printf("\n%d\n",num);
return 0 ;
}
输出效果如下:
针对本题的代码:
注意点:static关键字能保证每次调用跟着递增,不然你会发现num每次调用都是0
写递归应该先把要执行的步骤放在判断前面,然后在条件判断后面调用函数,
注意:如果输入的是0,0的二进制是一位,暂时只想到多加一个count来判断是不是0
int countBinary(int n){
static int num=-1;
static int count=-1;//用来判断n是不是一开始就是0
num++;
count++;//注意count在pta上必须写在外边,才会跟着递增
if(n!=0){
countBinary(n/2);
//codeblocks上把count++ 写在这后边答案是对的,但是在pta上就不对
}
else if(n==0 && count!=0)
return num;
else if(n==0 && count==0)
return 1;
}
6-10 实验6_7_最大公约数 (100 分)
设计递归函数int GCD(int a,int b);计算正整数a和b的最大公约数并返回。如GCD(32,48)为16。
GCD(a,b)递归定义为:
GCD(a,b)=GCD(b,a MOD b) 当 a MOD b≠0
GCD(a,b)=b 当 a MOD b=0
输入与输出要求: 输入两个正整数a和b,输出两数的最大公约数,占一行。
函数接口定义:
函数原型如下:
int GCD(int a , int b );
其中 a
和 b
都是用户传入的参数。a
和 b
的值不超过int
的范围。函数的返回值为a
和 b
的最大公约数。
裁判测试程序样例:
函数被调用的例子如下:
#include<stdio.h>
int GCD(int a , int b );
int main()
{
int a , b ;
scanf("%d%d", &a , &b );
printf( "%d\n" , GCD( a, b ) ) ;
return 0 ;
}
/* 请在这里填写答案 */
输入样例:
32 48
输出样例:
16
思路:
就根据题目给出的递推关系来写,边界就是temp%b==0
代码:
int GCD(int a , int b ){
static int temp=0;
temp=a;
a=b;
//b=temp%b;
if(temp%b!=0){
GCD(a,temp%b);
}
else
return b;
}
6-11 03_数列求值 (100 分)
现有序列: s = 1 + a + a2 +…+ an+1
其中a>0,n>0,且均为整数。 测试用例保证所有整数可以用int存储。 请写出递归求s的函数。
函数接口定义:
函数接口如下:
int evaluation(int n,int a);
其中 n
和 a
都是用户传入的参数,分别代表数列中的n和a,返回值为所求结果。
裁判测试程序样例:
函数被调用进行测试的例子如下:
#include <stdio.h>
int evaluation(int n,int a) ;
int main()
{
int n , a ;
scanf("%d%d",&n,&a);
printf("%d\n",evaluation(n,a));
return 0;
}
/* 请在这里填写答案 */
输入样例:
1 2
输出样例:
7
思路:
递推关系
evaluation(n,a)=1+evaluation(n-1,a)*a
边界:n==-1,此时evaluation(-1,a)=1
代码:
int evaluation(int n,int a){
if(n==-1)
return 1;
else
return 1+evaluation(n-1,a)*a;
}
总结:
这次作业主要练习递归,递归的关键是递推式和边界条件
递推关系不是一个式子就能表达完的,一般放在函数的最开头,注意要跟着递增的变量,定义时要用static关键字,再判断边界条件进行调用自己的函数
一个式子就能表达完的,比如最后一题或者斐波那契数列,就直接if else,把到达边界条件的情况,应该return的值求出来,调用递归的部分就直接return递归式
比如上边最后一题。
作业完成!