2021-05-22递归练习作

 

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 * 2​0​​ + 0 * 2​1​​ + 1 * 2​2​​ + 1 * 2​3​​ = 1101 % 10 + convert(110) * 2 ;

110 = 0 * 2​0​​ + 1 * 2​1​​ + 1 * 2​2​​ = 110 % 10 + convert(11) * 2;

11 = 1 * 2​0​​ + 1 * 2​1​​ = 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 + a​2​​ +…+ a​n+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递归式

比如上边最后一题。

作业完成!

 

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值