`
pengc825
  • 浏览: 8633 次
文章分类
社区版块
存档分类
最新评论

枚举生成排列的方法总结

 
阅读更多

枚举生成排列的方法总结

1. 利用递归的方法枚举1~n的所有不重数排列

思路大概就是对一个大小为n的容器,定义一个递归方法。

每次通过1~9的顺序不断进行放置,放置条件为这个数字在容器里面没有出现过。(递归方法)

直到放满容器为止打印出当前满足的排列。(递归边界条件)

实现代码如下:

/*
    利用递归的方法,求 1 ~ n 的全排列
 */
#include <iostream>
#include <cstdlib>

using namespace std;

long long Count;                        // 定义一个计数器,计数排列种数;

void Printf_Permutation(int n, int cur, int *Num) {     // 递归函数;
	if (cur == n) {                     // 递归边界;
		cout << "Num " << Count + 1 << " -> ";
		for ( int i = 1; i <= n; ++i ) {
			cout << Num[i];
			i == n ? cout << endl : cout << " ";

		}
		Count++;
	}
	else {
		for ( int i = 1; i <= n; ++i ) {     // 循环和递归调用嵌套的运用形式;
			int ok = 1;
			for ( int j = 1; j <= cur; ++j ) {   // 判断要填进去的数字是不是已经填过;
				if (i == Num[j]) ok = 0;
			}
			if (ok) {
				Num[cur + 1] = i;       // 吧满足条件的数字填进去,然后递归调用;
				Printf_Permutation(n, cur + 1, Num);
			}
		}
	}
}

int main( int argc, char const *argv[] ) {
	int n;
	cin >> n;
	int *Num = (int *)malloc(sizeof(int) * ( n + 1 ));  // 动态分配一个数组;

	Printf_Permutation(n, 0, Num);
	cout << "The All Of Permutation is " << Count << endl;
	return 0;
}


思考:博主分析这道题目的时候突然脑洞打开,试想想:递归能不能看成是循环层数未知(自动获取)的高级循环体结构。


2.利用递归的方法枚举1~n的所有可重数排列

​如果把问题改成:输入数组P,并按字典序输出数组A各元素的所有全排列。

那么问题也很简单

只需要把上面代码的 i == Num[j] 改成 setN[i] == Num[j] , Num[cur + 1] = i 改成 Num[cur + 1] = setN[i] 然后在 输入待排列的数组setN的时候排好序 。

为了可以出现可重的排序,所以能够递归的判断条件也要改成 countN<CountNum[setN[i] // 判断已经填进容器得某个元素个数是否小于它原本有的元素个数。

为了避免出现 1 1 和 1 1 未两种情况的现象发生,所以必须在循环下面加一条判断条件 if(i==1||setN[i]!=setN[i-1]) 即只有不同的数字才能作为不用的排列填充。

实现代码如下:

/*
    利用递归的方法,求 1 ~ n 的全排列
 */
#include <iostream>
#include <cstdlib>

using namespace std;

long long Count;                        // 定义一个计数器,计数排列种数;

void Printf_Permutation(int n, int cur, int *Num) {     // 递归函数;
	if (cur == n) {                     // 递归边界;
		cout << "Num " << Count + 1 << " -> ";
		for ( int i = 1; i <= n; ++i ) {
			cout << Num[i];
			i == n ? cout << endl : cout << " ";

		}
		Count++;
	}
	else {
		for ( int i = 1; i <= n; ++i ) {     // 循环和递归调用嵌套的运用形式;
			int ok = 1;
			for ( int j = 1; j <= cur; ++j ) {   // 判断要填进去的数字是不是已经填过;
				if (i == Num[j]) ok = 0;
			}
			if (ok) {
				Num[cur + 1] = i;       // 吧满足条件的数字填进去,然后递归调用;
				Printf_Permutation(n, cur + 1, Num);
			}
		}
	}
}

int main( int argc, char const *argv[] ) {
	int n;
	cin >> n;
	int *Num = (int *)malloc(sizeof(int) * ( n + 1 ));  // 动态分配一个数组;

	Printf_Permutation(n, 0, Num);
	cout << "The All Of Permutation is " << Count << endl;
	return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。By PengCoX ( Pengc825@foxmail.com )

分享到:
评论

相关推荐

    C 代码 枚举、生成、随机化、排名和取消排名组合 对象包括组合、组合、格雷码、索引集、 分区、排列、多项式、子集和杨表.rar

    C实用代码

    基于 .NET 6.0控制台框架的随机密码生成器源代码,可设置密码长度及组成形式,含可执行文件

    基于 .NET 6.0控制台框架的...- 字符池排列顺序:数字-字母-符号(默认字母为必须,因此放在中间)。 - 根据密码长度,生成字符数组,每个元素都从字符池中随机取值。 - 密码字符取值类型采用了枚举(Flags)进行判定。

    枚举:Yang-Baxter方程的集合理论解

    parserB.g 这里的方法包括:每当集中器足够小时,发送T集中器中的所有排列作为约束,并且集中器的那些排列最多移动3点。 parserC.g 此处的方法是发送T扶正器生成集最多3个元素的所有乘积作为约束。 这些文件用于...

    生成验证码控件

    LayoutDirection":控件各部分排列方向,排列的部分包括文本框、图片、"换一张图片"文本 EnableClientValidate:是否使用客户端脚本验证,验证内容包括是否为空、长度是否正确 ImageStyle:验证码图像样式 其中Image...

    黑盒PAYLOAD_生成技法.pdf

    而整个过程的核心就在于如何建立场景规则集,Gaba提到了几种方式,包括人为总结(自定义)、参数黑白名单、根据类型进行排列组合、根据历史记录进行范围调整等。 面对“东北人不脱貂”而淋漓大汗的Gaba,混迹于各大...

    Tomcat6.0_API帮助文档

    索引 包含按字母顺序排列的所有类、接口、构造函数、方法和字段的列表。 上一个/下一个 这些链接使您可以转至下一个或上一个类、接口、软件包或相关页面。 框架/无框架 这些链接用于显示和隐藏 HTML 框架。所有页面...

    采用启发式搜索求解TSP问题(C语言)

    最后采用枚举的方法,确定从不同最小生成树开始构造的闭合回路中距离最小的一个 ,即最短城市序列 。 由于闭合回路中每个节点的度都为2 ,因此在构造闭合回路时需要处理最小生成树中度不等于2的节点。处理时,第一步是...

    API之网络函数---整理网络函数及功能

    WNetCloseEnum 结束一次枚举操作 WNetConnectionDialog 启动一个标准对话框,以便建立同网络资源的连接 WNetDisconnectDialog 启动一个标准对话框,以便断开同网络资源的连接 WNetEnumResource 枚举网络资源 ...

    C#全能速查宝典

    2.1.14 LayoutMdi方法——排列子窗体 141 2.1.15 Load事件——窗体加载事件 141 2.1.16 MaximizeBox属性——是否显示最大化按钮 142 2.1.17 Maximum属性——设置数字显示框的最大值 142 2.1.18 MDI窗体——多文档...

    二进制文件合并工具软件 PackagingTool

    (3)除了生成bin,同时会生成一份.h文件,该文件已构建枚举,MCU可以直接引用索引调用。 (4)可以重复导入列表,仅导入该.h文件即可,提高开发和生产效率! 该软件绿色、免费、短小,欢迎使用!也欢迎分享!

    ACM算法模板和pku代码

    r-错位排列生成算法 图论 传递闭包 欧拉回路判定 有向图欧拉路径 二分图最大匹配 匈牙利算法 二分图最大匹配 HK算法 二分图最大权匹配 KM算法 割边 强连通分量 缩点 Kosaraju算法 最大团 最小树形图 无...

    LeetCode解题总结

    LeetCode解题总结 1. 数组 1.1 从有序数组中删除重复元素 1.2 在排序数组被旋转后进行查找 1.3 寻找两个排序数组的中位数 1.4 最长连续序列 1.5 累加和 1.6 移除数组中指定值 1.7 下一个排列 1.8 第n个全排列 1.9 ...

    张孝祥 7k面试题 银行业务调度系统改进

    一、系统的取号机只有三种方式的取号(普通客户,快速客户,vip客户),所以采用枚举的方式是比较合适的,因为枚举能产生固定个数的对象,用起来也比较方便。 二、创建普通服务窗口类,下面有两个子类(快速服务...

    modular-cv:LaTeX 中的模块化简历,可以为不同的受众轻松生成不同的简历

    模块化简历 LaTeX 中的模块化简历,可以为... (如果您排版一次,枚举列表将不会按相反顺序排列。) 部分通过\input{}命令合并到主文件中。 通过在这些行前面加上%字符,简单地注释掉要排除的部分。 [cc]: ) [ctan]:

    Python Cookbook

    16.9 在Python中模拟枚举 580 16.10 在创建列表推导时引用它自身 583 16.11 自动化py2exe将脚本编译成Windows可执行文件的过程 585 16.12 在UNIX中将主脚本和模块绑成一个可执行文件 587 第17章 扩展和嵌入 590...

    数学建模真题matlab编程 MATLAB数学建模工具箱

    % *krusk - 最小生成树kruskal算法mex程序 % *dijkstra - 最短路dijkstra算法mex程序 % *dynprog - 动态规划 % % % 图形 % plot - 平面曲线(一元函数) % plot3 - 空间曲线 % mesh - 空间曲面(二元函数) % *meshf...

    Matlab数学建模工具箱

    % *krusk - 最小生成树kruskal算法mex程序 % *dijkstra - 最短路dijkstra算法mex程序 % *dynprog - 动态规划 % % % 图形 % plot - 平面曲线(一元函数) % plot3 - 空间曲线 % mesh - 空间曲面(二元函数) % *meshf...

    MATLAB数学建模工具箱

    % *krusk - 最小生成树kruskal算法mex程序 % *dijkstra - 最短路dijkstra算法mex程序 % *dynprog - 动态规划 % % % 图形 % plot - 平面曲线(一元函数) % plot3 - 空间曲线 % mesh - 空间曲面(二元函数) % *meshf...

    ASP.NET 验证码控件及其好用【推荐】

    LayoutDirection":控件各部分排列方向,排列的部分包括文本框、图片、"换一张图片"文本 EnableClientValidate:是否使用客户端脚本验证,验证内容包括是否为空、长度是否正确 ImageStyle:验证码图像样式 其中...

Global site tag (gtag.js) - Google Analytics