Johnson-Trotter 生成全排列算法
核心五部曲:
① 初始化元素数组[1,2,3,4],初始化方向数组[0,0,0,0] (0代表左移,1代表右移)
② 找到最大的可移动元素
可移动的两个条件:
1. 元素移动后不会越界([4,3,2,1],如果4方向为左,不能移动)
2. 即将交换的元素不能比本元素大([3,4,2,1],如果3的方向为右,不能移动)
③ 移动一次元素
④ 移动后,将元素列表中比移动元素大的所有元素的方向翻转(0-1,1-0)
⑤ 如果列表没有可以移动的元素,结束
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;vector<int> nums; // 元素数组
vector<int> dir; // 方向数组,0代表左移,1代表右移
int n; // 元素数组大小 // 打印
void Print(){for(int i = 0; i < n; i++) cout<<nums[i]<<" ";cout<<endl;
}// 调转当前移动元素更大的所有元素的方向
void changeDir(int num){for(int i = 0; i < n; i++) {if(num < nums[i]) {if(dir[i] == 0) dir[i] = 1;else dir[i] = 0;}}
} // 交换位置
void SWAP(int id1, int id2) {swap(nums[id1], nums[id2]);swap(dir[id1], dir[id2]);
}// 找到可以移动的最大元素
int canMove() {int maxIndex = -1;int maxNum = -1;for(int i = 0; i < n; i++) {if(dir[i] == 0 && i > 0 && nums[i] > nums[i - 1]) {if(maxNum < nums[i]) {maxIndex = i;maxNum = nums[i];}}else if(dir[i] == 1 && i < n - 1 && nums[i] > nums[i + 1]) {if(maxNum < nums[i]) {maxIndex = i;maxNum = nums[i];}}}Print(); // 每一次交换都需要调用一次canMove函数,因此在此打印 return maxIndex;
}// 移动
void move(int index) {// 左移 if(dir[index] == 0 && index > 0 && nums[index] > nums[index - 1]) {SWAP(index, index - 1);}// 右移 else if(dir[index] == 1 && index < n - 1 && nums[index] > nums[index + 1]){SWAP(index, index + 1);}
} int main() {cout << "Enter the size of number seq: ";cin >> n;// 初始化 for(int i = 0; i < n; i++) {nums.push_back(i + 1); dir.push_back(0); // 初始化元素都向左 }while(true) {// 1.找到可以移动的最大元素的索引 int moveIndex = canMove();if(moveIndex != -1) {int moveNumber = nums[moveIndex];// 2.移动该元素 move(moveIndex);// 3.移动完调转所有比它大的元素的方向changeDir(moveNumber);}// 4.找不到可移动元素,结束循环 else break;}return 0;
}
Johnson-Trotter 生成全排列算法相关推荐
- JOHNSON TROTTER 的全排列算法
/*试一试Johnson Trotter的算法*/ /* 数组初始为123 标记数组b[]的初始值是011(0 不可移动,1否) /要不利用二维数组--?/ b[]中找值为一的 然后看 ...
- Steinhaus-Johnson-Trotter 生成全排列算法
Steinhaus-Johnson-Trotter算法是一种基于最小变换的全排列生成算法,对于排列a[1...n],该算法通过将a[i],与a[i-1](或a[i+1])进行交换,生成下一个排列,直到 ...
- 算法设计与分析——Johnson Trotter算法
目录 前言 一.算法思想分析 二.算法效率分析 三.算法代码 C语言代码 后记 前言 排列与组合问题,无论是在我们生活中还是项目实际运用中,都说非常之常见的.那么,如何去运用算法思想生成全排列(一组元 ...
- johnson_trotter(生成排列算法)
思路和步骤: 将数字赋予方向属性 理解什么叫可移动方向(后面在图片1中说明) 判断是否存在可移动元素 bool judge_move(init* n_n, int n); 定义一个全局int k--& ...
- [通用技术]在不同语言中用协程实现全排列算法(C++/Lua/Python/C#)
我这里实现全排列的基本算法如下(C++): 1 #include <algorithm> 2 #include <iostream> 3 #include <vector ...
- 递归生成全排列【C/C++】
简述 生成一个序列的全排列 算法伪代码 输入: n:表示序列长度 char* a: 对应的序列 输出: 这个序列的全排列 满足要求: 必须使用全排列 对应的代码的参数 void pomi(char * ...
- 通过康托逆展开生成全排列
康托展开的公式是:X=an*(n-1)!+an-1*(n-2)!+...+ai*(i-1)!+...+a2*1!+a1*0! 其中,ai为当前未出现的元素中是排在第几个(从0开始). 例如,有一个 ...
- 全排列的java算法_全排列算法原理和实现
评论 # re: 全排列算法原理和实现 回复 更多评论 #include #include #define CHESSNUM 9 using namespace std; /*********** ...
- 生成全排列算法的实现(Johnson-Trotter)
生成全排列算法的实现(Johnson-Trotter) 如下是用Johnson-Trotter算法实现的n个数据的全排列,这些数据可任意,因为对于任意n个数据,都可与1至n这n个整数一一对应,因此,在 ...
最新文章
- Modelsim do文件的自动化仿真及模板
- jq实现div移入与移出以及获得与失去焦点
- wpf 点击某控件范围之外的区域 该控件隐藏_iOS平台设计规范(八)控件Controls...
- Boost:双图bimap与Boost xpressive的测试程序
- tyvj 1067 合唱队形 dp LIS
- python高级编程技巧
- 使用计算机的硬件及参数,硬件参数怎么看?如何选配电脑硬件?
- python安装无法直接安装的包
- 条件指示符 #ifdef 的用法
- python字符串替换
- Android之简洁天气
- 9款常用的数据可视化工具推荐
- T32使用-----抓取rpm dump
- 培养学生数学核心素养,不能制造“数学小糊涂”!
- html中滚动速度怎么调节,html – 图像调整大小导致滚动速度慢
- python中import re_python中re模块
- 计算机专业毕业论文怎么写够字数,本科生毕业论文要求多少字
- 如何使用DDexec在Linux上隐蔽运行二进制文件
- 对接支付宝php版easysdk接口分享
- ES 中时间日期类型 “yyyy-MM-dd HH:mm:ss” 的完全避坑指南