康托展开 全排列
2016-04-27 15:59
483 查看
今天找到了一篇非常好的介绍康托展开的文章!!!
http://www.cnblogs.com/1-2-3/archive/2011/04/25/generate-permutation-part2.html
其核心是这一张图:
根据这篇文章,写出生成按序排列的全排列非常的简单:
和原来的通过递归+回溯(http://blog.csdn.net/puppylpg/article/details/45287249)来生成全排列相比思路上简单了不少!
http://www.cnblogs.com/1-2-3/archive/2011/04/25/generate-permutation-part2.html
其核心是这一张图:
根据这篇文章,写出生成按序排列的全排列非常的简单:
#include <iostream> #include <vector> #include <string> #define N 4 using namespace std; vector<char> letter; //存储所需字母表 void initLetter() //初始化字母表 { for(int i = 0; i < N; ++i){ letter.push_back('A' + i); } } int fact(int n) //阶乘 { int result = 1; for(int i = 1; i <= n; ++i){ result *= i; } return result; } void output(vector<char>& v) //输出生成的结果 { for(vector<char>::iterator it = v.begin(); it != v.end(); ++it){ cout << *it; } cout << endl; } void division(int n) //核心算法:辗转相除生成排列 { initLetter(); //每次先初始化字母表 vector<char> result; int value, div; for(int i = N - 1; i >= 0; --i){ //从(N-1)!除起 div = fact(i); value = n / div; //商为当前字母表下标 n = n % div; //余数继续用于辗转相除 result.push_back(letter[value]); //商对应的字母加入到结果 letter.erase(letter.begin() + value); //从原始字母表中删除(参数必须是iterator) } output(result); } int main() { int num = fact(N); for(int i = 0; i < num; i++){ //从0~(N! - 1),每一个数对应一个排列 division(i); } return 0; }
和原来的通过递归+回溯(http://blog.csdn.net/puppylpg/article/details/45287249)来生成全排列相比思路上简单了不少!
#include <iostream> #include <vector> #define N 4 using namespace std; vector<char> letter; //存储所需字母表 vector<bool> visited; //标记 vector<char> result; void initLetter() //初始化字母表 { for(int i = 0; i < N; ++i){ letter.push_back('A' + i); visited.push_back(false); result.push_back(' '); //顺便给result开辟空间 } } void output(vector<char>& v) //输出生成的结果 { for(vector<char>::iterator it = v.begin(); it != v.end(); ++it){ cout << *it; } cout << endl; } void f(int n) //核心算法:回溯。n是第n位 { if(n == N){ //如果已经放置了N位,说明生成了一个排列 output(result); return; } for(int i = 0; i < N; i++){ //对于每一位 if(visited[i] == false){ //如果没有被用过,则可以用 visited[i] = true; result = letter[i]; f(n + 1); //递归继续生成下一位 visited[i] = false; //回溯 } } } int main() { initLetter(); f(0); return 0; }