一、算法要求
设计一个递归算法生成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表示该元素出现。
文档供本人学习笔记使用,仅供参考。