【全排列问题(Perm)】“递归与分治策略”——《算法设计与分析(第五版)》


一、算法要求

设计一个递归算法生成n个元素{r1,r2,…,rn}的全排列。

1. 思路

实现思想:将整组数中的所有的数分别与第一个数交换,这样就总是在处理后n-1个数的全排列。

设R={r1,r2,…,rn}是要进行排列的n个元素,Ri=R-{ri}。集合X中元素的全排列记为 Perm(X)。
(ri)Perm(X)表示在全排列 Perm(X)的每个排列前加上前缀 ri得到的排列。
R的全排列可归纳定义如下:
		当n=1时,Perm(R)=(r),其中r是集合R中唯一的元素;
		当n>1时,Perm(R)由(r1)Perm(R1),(r2)Perm(R2)…(rn)Perm(Rn)构成。

2. 示例

在这里插入图片描述


二、完整代码

1. 主文件

main.cpp:

// Project1_1: 全排列问题(Perm)

#include "Basic1.h"
int main()
{
    string simple; // 用于展示所有整数划分形式
    int n ; // 用于整数划分的整数

    cout << "Please enter a positive integer for integer division: ";
    cin >> n;
    cout << "\nAll divided into: " << endl;
    ResultDisplay(n, n, simple);
    cout << "\nThe number of divisions is: " 
        << IntegerDivision(n, n) << endl;

    return 0;

}

2. 头文件

Basic1.h:

#pragma once

#ifndef __BASIC1__
#define __BASIC1__

#include <iostream>
#include <string>
#include <iomanip>
using namespace std;

// 递归展示所有划分形式
void ResultDisplay(int n, int m, string s) {
    if (n == 1 || m == 1) {
        for (int i = 0; i < n - 1; i++)
            s += string("1+");
        cout << setw(20) << right << s << "1" << endl;//片尾换行
        return;
    }
    else if (m > n) {
        return ResultDisplay(n, n, s);
    }
    else if (n == m) {
        cout << setw(20) << s << n << endl;
        return ResultDisplay(n, m - 1, s);
    }
    if ((n - m) != 0)
        //利用to_string,将数字常量转换为字符串
        ResultDisplay(n - m, m, s + to_string(m) + string("+"));
    else
        cout << s << m << endl;
    ResultDisplay(n, m - 1, s);
}

// 递归计算划分数
int IntegerDivision(int n, int m)
{
    if (n == 1 || m == 1)
        return 1;
    else if (n < m)
        return IntegerDivision(n, n);
    else if (n == m)
        return 1 + IntegerDivision(n, m - 1); //影响总分割次数
    else if (n > m)
        return IntegerDivision(n, m - 1) + IntegerDivision(n - m, m);
}



#endif


3. 效果展示

在这里插入图片描述


三、补充

使用递归函数生成子集:

生成n个元素的所有子集,有2^n个。
例如:E={a,b,c}的子集有
	{} {a} {b} {c} {a,b} {a,c} {b,c} {a,b,c}
    000,100,010,001,110,  101,  011,   111
思想:生成对应与元素出现位置的数组,0表示该元素不出现,1表示该元素出现。

文档供本人学习笔记使用,仅供参考。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

NI'CE'XIAN

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值