递归的运用---实现排列型,组合型,指数型枚举的过程

今天下午主要是看了一下这个递归是如何实现枚举的,分别是对应的不同的枚举的方式,指数型枚举,组合型枚举;

1.第一题

下面的这个是代码:

1)接下来的三个题目代码基本上都是下面的这个结构,funx函数负责的就是我们的这个递归的过程

2)上面的这个图片里面的案例其实就已经说明了很多问题,就是这个输入输出的内容和规律我们肯定可以明白这个枚举的过程的;

3)cnt控制的事我们输出的内容的数据个数,里面有一个for循环是对于这个空格进行输出的控制的;

4)func(i+1)就是从后面的一个数据开始继续进行这个递归的过程,例如,之前的数据是1开头的,这个时候我们就需要从2开始这个递归的过程;

5)cnt--就是我们每一次进行这个回溯的过程,也就是回到之前的状态,再次做出选择;

ini 复制代码
#include<iostream>
using namespace std;
int num[15],cnt,n;
void func(int s)
    {
    for(int i=s;i<=n;i++)
    {
        num[cnt]=i;
        cnt++;
        for(int j=0;j<cnt;j++)
            {
            if (j != 0) cout << " ";
            cout<<num[j];
        }
        cout<<endl;
        func(i+1);
        cnt--;
    }
}
int main()
    {
    cin>>n;
    func(1);
    return 0;
}

2.第二题

下面的这个算是组合型枚举,输入的数据的参数是确定的,输入的参数是两个,输出的数据的个数也是确定的,不像上面的那个样子输出的里面的个数有波动;

下面的这个是我们的代码:

1)func调用的时候第一个参数是1表示从几开始,m表示的就是剩下 的需要进行选择的这个数据的个数;

2)left==0表示的就是我们的这个递归的结束的条件,直接进行这个输出即可,cnt控制的就是我们的输出里面的个数,这个进行是否为0判断主要是为了解决这个输出里面的空格的问题;

3)第二个for循环表示的就是我们的递归的过程,func(i+1)表示的就是接着递归,left-1表示的这个新一轮剩下的这个数据的个数,cnt--就是进行回溯的过程;

ini 复制代码
#include<iostream>
using namespace std;
int n, m, num[15], cnt;
void func(int s, int left)
{
    if (left == 0) {
        for (int i = 0; i <cnt; i++)
        {
            if (i != 0)
            {
                cout << " ";
            }
            cout << num[i];
        }
        cout << endl;
        return;
    }
    for (int i = s; i <= n - left + 1; i++)
    {
        num[cnt] = i;
        cnt++;
        func(i + 1, left - 1);
        cnt--;
    }
}
int main()
{
    cin >> n >> m;
    func(1, m);
    return 0;
}

3.第三题

下面的这个是题目:排列行枚举主要强调的就是这个排列的过程,因此这个选过的数据就不可以再次出现了;

下面的这个事代码:

1)func还是实现我们的这个逻辑的函数,left==0还是进行这个递归结束的条件的判断说明;

2)mark数组主要就是标记我们的这个数据有没有被选中过,有没有被使用过,0表示的就是没有被使用过,这个时候我们就需要放到这个数组里面去,然后赋值为1,表示这个数据已经被使用了,后面不可以再被选中

3)func(left-1)表示的就是这个时候需要选择的个数减少了一个,接下来就是回溯,也就是回到开始的状态,这个时候就是cnt--,回溯的时候,我们之前使用数据是可以被再次使用的,也就是相当于开始新的一轮,因此这个时候我们的mark,这个表示数据有没有被使用的数组,也是需要置为0,表示处于原始没有被使用的状态,开始新一轮的选择;

ini 复制代码
#include<iostream>
using namespace std;
int n, num[15], mark[15], cnt;
void func(int left)
{
    if (left == 0)
    {
        for (int i = 0; i < cnt; i++)
        {
            if (i != 0) {
                cout << " ";
            }
            cout << num[i];
        }
        cout << endl;
        return;
    }
    for (int i = 1; i <= n; i++)
    {
        if (mark[i] == 0)
        {
            mark[i] = 1;
            num[cnt] = i;
            cnt++;
            func(left - 1);
            cnt--;
            mark[i] = 0;
        }
    }
}
int main()
{
    cin >> n;
    func(n);
    return 0;
}
相关推荐
焦耳加热3 小时前
阿德莱德大学Nat. Commun.:盐模板策略实现废弃塑料到单原子催化剂的高值转化,推动环境与能源催化应用
人工智能·算法·机器学习·能源·材料工程
wan5555cn3 小时前
多张图片生成视频模型技术深度解析
人工智能·笔记·深度学习·算法·音视频
u6063 小时前
常用排序算法核心知识点梳理
算法·排序
蒋星熠6 小时前
Flutter跨平台工程实践与原理透视:从渲染引擎到高质产物
开发语言·python·算法·flutter·设计模式·性能优化·硬件工程
小欣加油6 小时前
leetcode 面试题01.02判定是否互为字符重排
数据结构·c++·算法·leetcode·职场和发展
3Cloudream6 小时前
LeetCode 003. 无重复字符的最长子串 - 滑动窗口与哈希表详解
算法·leetcode·字符串·双指针·滑动窗口·哈希表·中等
王璐WL6 小时前
【c++】c++第一课:命名空间
数据结构·c++·算法
空白到白7 小时前
机器学习-聚类
人工智能·算法·机器学习·聚类
索迪迈科技7 小时前
java后端工程师进修ing(研一版 || day40)
java·开发语言·学习·算法
zzzsde7 小时前
【数据结构】队列
数据结构·算法