浙大版《C语言程序设计实验与习题指导(第4版)》专题 递归函数的简单运用(实验10-2——实验10-8)

作者:雨中春树万人家

一、递归知识点梳理

1.定义:函数调用自身,此类函数统称为递归函数。

2.特点:将一个大型的、复杂的问题,转化成与原问题类型相同,规模缩小的问题。

3.实现方法:

①注意函数的终止条件。终止时,一般对某一个变量赋值或直接返回某个常数。

②注意从n到n-1的过渡条件。常见的过渡条件有加减某一项、乘除某一项。

③如果涉及多个步骤,要考虑步骤的先后顺序。例如:从高位到低位输出一个数,与从低位到高位输出一个数,则输出n%10与自身调用(n/10充当变量)的先后顺序是相反的。

仅靠递归函数无法较好地表达过渡条件时,可以新建其他函数,运用模块化程序设计思想

过渡条件用具体的数学表达式实现,n-1时调用函数自身

二、递归习题分析

10-2 递归实现指数函数(15分)

本题要求实现一个计算x^n(n≥1)的函数。

函数接口定义:

double calc_pow( double x, int n );

函数calc_pow应返回xn次幂的值。建议用递归实现。题目保证结果在双精度范围内。

裁判测试程序样例:

#include <stdio.h>

double calc_pow( double x, int n );

int main()
{
    double x;
    int n;

    scanf("%lf %d", &x, &n);
    printf("%.0f\n", calc_pow(x, n));

    return 0;
}

/* 你的代码将被嵌在这里 */

输入样例:

2 3

结尾无空行

输出样例:

8

代码(含注释):

double calc_pow( double x, int n )
{
    if(n==1)
        return x;//终止条件:当n==1成立时,直接返回x
    else
        return x*calc_pow(x,n-1);
    //从n到n-1的过渡条件是乘以x
}

 10-3 递归计算Ackermenn函数(15分)

本题要求实现Ackermenn函数的计算,其函数定义如下:

浙大版《C语言程序设计实验与习题指导(第4版)》专题 递归函数的简单运用(实验10-2——实验10-8)

函数接口定义:

int Ack( int m, int n );

其中mn是用户传入的非负整数。函数Ack返回Ackermenn函数的相应值。题目保证输入输出都在长整型

范围内。

裁判测试程序样例:

#include <stdio.h>

int Ack( int m, int n );

int main()
{
    int m, n;

    scanf("%d %d", &m, &n);
    printf("%d\n", Ack(m, n));

    return 0;
}

/* 你的代码将被嵌在这里 */

输入样例:

2 3

结尾无空行

输出样例:

9

结尾无空行

代码(含注释):

 

int Ack( int m, int n )
{
    if(m==0)
        return n+1;
    else if(n==0&&m>0)
        return Ack(m-1,1);
    else
        return Ack(m-1,Ack(m,n-1));
    //本题按照图片即可进行递归
}

10-4 递归实现顺序输出整数 (15 分)

本题要求实现一个函数,对一个整数进行按位顺序输出。

函数接口定义:

void printdigits( int n );

函数printdigits应将n的每一位数字从高位到低位顺序打印出来,每位数字占一行。

裁判测试程序样例:

#include <stdio.h>

void printdigits( int n );

int main()
{
    int n;

    scanf("%d", &n);
    printdigits(n);

    return 0;
}

/* 你的代码将被嵌在这里 */

输入样例:

12345

结尾无空行

输出样例:

1
2
3
4
5

结尾无空行 

代码(含注释)

void printdigits( int n )
{
    if(n<10)
        printf("%d",n);//终止条件:n只有1位时,直接输出n
    else
    {
        printdigits(n/10);//注意过渡条件是n/10
        printf("\n%d",n%10);//由于从高位向低位输出,应该先调用自身,再输出n%10
    }
}

10-5 递归求阶乘和 (15 分)

本题要求实现一个计算非负整数阶乘的简单函数,并利用该函数求 1!+2!+3!+...+n! 的值。

函数接口定义:

double fact( int n );
double factsum( int n );

函数fact应返回n的阶乘,建议用递归实现。函数factsum应返回 1!+2!+...+n! 的值。题目保证输入输出在双精度范围内。

裁判测试程序样例:

#include <stdio.h>

double fact( int n );
double factsum( int n );

int main()
{
    int n;

    scanf("%d",&n);
    printf("fact(%d) = %.0f\n", n, fact(n));
    printf("sum = %.0f\n", factsum(n));

    return 0;
}

/* 你的代码将被嵌在这里 */

输入样例1:

10

结尾无空行

输出样例1:

fact(10) = 3628800
sum = 4037913

结尾无空行

输入样例2:

0

输出样例2:

fact(0) = 1
sum = 0

 代码(含注释):

double fact( int n )
{
    if(n==1||n==0)
        return 1;//终止条件
    else
        return n*fact(n-1);//从n-1到n的过渡:乘以n
}
double factsum( int n )
{
    double sum;
    if(n==1)
        sum=fact(n);
    else if(n==0)
        sum=0;//终止条件
    else
        sum=fact(n)+factsum(n-1);
    //从n-1到n的过渡:加上fact(n)
    //过渡部分是具体表达式,左边结果、右边n-1时结果都用递归函数代入表示
    return sum;
}

10-6 递归求简单交错幂级数的部分和 (15 分)

本题要求实现一个函数,计算下列简单交错幂级数的部分和:

f(x,n)=x−x^2+x^3−x^4+⋯+(−1)^(n−1)*x^n

函数接口定义:

double fn( double x, int n );

其中题目保证传入的n是正整数,并且输入输出都在双精度范围内。函数fn应返回上述级数的部分和。建议尝试用递归实现。

裁判测试程序样例:

#include <stdio.h>

double fn( double x, int n );

int main()
{
    double x;
    int n;

    scanf("%lf %d", &x, &n);
    printf("%.2f\n", fn(x,n));

    return 0;
}

/* 你的代码将被嵌在这里 */

输入样例:

0.5 12

结尾无空行

输出样例:

0.33

结尾无空行

 代码(含注释)

double fact(double x,double n)//fact用于计算x的n次方
{
    if(n==1)
        return x;
    else
        return x*fact(x,n-1);
}
int positive(int n)//positive用于计算系数的正负
{
    if(n%2==1)
        return 1;
    else
        return -1;
}
double fn( double x, int n )
{
    double sum;
    if(n==1)
        sum=x;//终止条件
    else
        sum=positive(n)*fact(x,n)+fn(x,n-1);//fn函数内部无法简便表达过渡条件,故构造positive,fact函数
    return sum;//过渡条件:加上positive(n)*fact(x,n),即x的n次方(正负号依据n的奇偶性确定)
}

10-8 递归求Fabonacci数列 (10 分)

本题要求实现求Fabonacci数列项的函数。Fabonacci数列的定义如下:

f(n)=f(n−2)+f(n−1) (n≥2),其中f(0)=0,f(1)=1。

函数接口定义:

int f( int n );

函数f应返回第n个Fabonacci数。题目保证输入输出在长整型范围内。建议用递归实现。

裁判测试程序样例:

#include <stdio.h>

int f( int n );

int main()
{
    int n;

    scanf("%d", &n);
    printf("%d\n", f(n));

    return 0;
}

/* 你的代码将被嵌在这里 */

输入样例:

6

结尾无空行

输出样例:

8

结尾无空行

代码(含注释)

int f( int n )
{
    if(n==0)
        return 0;
    else if(n==1||n==2)
        return 1;//终止条件(注意题目对n==0的要求)
    else
        return f(n-1)+f(n-2);//过渡:直接调用f(n-1) f(n-2)并相加
}

三、总结

以上为递归的简单运用,注意分析过渡条件、终止条件,即可解决递归的简单问题。

感谢您的浏览,敬请期待后续更新。 

 

上一篇:组合数学 - The Intriguing Obsession


下一篇:第五周学习总结