zoukankan      html  css  js  c++  java
  • 2019年2月4日训练日记(递归学习小结)

    今天简单写一下有关递归方面的小结:

    递归

    概念:当函数的定义中,其内部操作又直接或间接的出现对自身的调用,则这样的程序嵌套为递归定义。
    函数直接调用其自身,称为直接递归,间接调用其自身,称之为间接递归

    能够用递归算法解决的问题,一般满足如下要求

    一、需要求解的问题可以转化为子问题求解,其子问题的求解方法与原问题相同,只是规模上的增大或减小。
    二、递归调用的次数是有限的;必须有递归结束的条件(称为递归边界)。

    递归应用举例:
    一、求两个数的最大公约数,可以用枚举因子的方法,从两者中较小的数字枚举到能被两个数同时整除且是最大公约数的方法;也可以用辗转相除法,这里采用递归实现辗转相除算法。
    方法一:

    #include<iostream>
    using namespace std;
    int gcd(int ,int );
    int main()
    {
        int m,n;
        cin>>m>>n;
        cout<<"gcd="<<gcd(m,n)<<endl;
        return 0;
    }
    int gcd(int m,int n)
    {
        return n==0?m:gcd(n,m%n);
    }
    

    方法二:
    二进制最大公约数算法

    #include<iostream>
    using namespace std;
    int gcd(int m,int n)
    {
        if(m==n)return m;
        if(m<n)return gcd(n,m);
        if(m%2==0)
        {
            if(n%2==0)return 2*gcd(m/2,n/2);
                else return gcd(m/2,n);
        }
        else
        {
            if(n%2==0)return gcd(m,n/2);
            else return gcd(n,m-n);
        }
    }
    int main()
    {
        int m,n;
        cin>>m>>n;
        cout<<gcd(m,n)<<endl;
        return 0;
    }
    

    此程序递归终止条件:gcd(m,m)=m.
    递归关系式:m<n时:gcd(m,n)=gcd(n,m)
    m为偶数,n为偶数:gcd(m,n)=2*gcd(m/2,n/2)
    m为偶数,n为奇数:gcd(m,n)=gcd(m/2,n)
    m为奇数,n为偶数:gcd(m,n)=gcd(m,n/2)
    m为奇数,n为奇数:gcd(m,n)=gcd(n,m-n)
    该方法和方法一相比更适合求高精度数的最大公约数,因为只涉及除2和减法操作,而辗转相除法则需要用到高精度除法。
    这种求最大公约数的方法也是第一次涉及到。

    二、已知一个一维数组a1…n,又已知一整数m。如能使数组a中任意几个元素之和等于m,则输出YES,反之输出NO。
    采用全局变量编写程序如下:

    #include<iostream>
    using namespace std;
    const int max1=51;
    int a[max1],n,m;
    bool flag;
    void sum(int ,int );
    int main()
    {
        cin>>n;
        for(int i=1;i<=n;i++)
            cin>>a[i];
            cin>>m;
        flag=false;
        sum(n,m);
        if(flag)cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
        return 0;
    }
    void sum(int n,int m)
    {
        if(a[n]==m)flag=true;
        else if(n==1)return;
        else
        {
            sum(n-1,m-a[n]);
            sum(n-1,m);
        }
    }
    

    其实这个程序我总是感觉会超时或者超内存,不过还好,题目给的n<25,数据数量有限且不算太多,但是如果没有这个限制...数据过多过大时总觉得这个程序会出现问题。

  • 相关阅读:
    ES6 | 关于class类 继承总结
    ES6 | class类的基本语法总结
    开发辅助 | 阿里图标库iconfont入门使用
    JS基本功 | JavaScript专题之数组 方法总结
    前端模块化 | 解读JS模块化开发中的 require、import 和 export
    IOS开发中UITableView和UITableViewCell的几种样式
    SSM项目的搭建
    Linux离线安装Docker
    Http项目转Https项目
    SpringBoot项目的搭建
  • 原文地址:https://www.cnblogs.com/study-hard-forever/p/12130065.html
Copyright © 2011-2022 走看看