permulation and review
2016-05-28 14:31
281 查看
相关知识:next_permulation 、prev_permulation 算法
题目来源:http://zion.sysu.edu.cn/m/ass/6296
题意:
Give you n numbers, and you can have n! permutations.
Then you can sort them with their lexicographically order.
For example, if n = 3 then we have 6 sorted permutations.
0 1 2
0 2 1
1 0 2
1 2 0
2 0 1
2 1 0
The class permu is a permutation.
You have to overload some operators like ++, –, <<
Hint:
实现前置++, 后置++, 前置–, 后置–, 输出流。
++使当前排列变为字典序比他大一个的排列。例如0 1 2会变成 0 2 1 如果是2 1 0则会变成0 1 2
–使当前排列变为字典序比他小一个的排列。例如2 1 0 会变成2 0 1 如果是0 1 2 则会变成2 1 0
输出流 输出格式为n个数字,每两个数字之间用空格隔开。行末没有空格和换行(换行在main.cpp中已经有了)
题目来源:http://zion.sysu.edu.cn/m/ass/6296
题意:
Give you n numbers, and you can have n! permutations.
Then you can sort them with their lexicographically order.
For example, if n = 3 then we have 6 sorted permutations.
0 1 2
0 2 1
1 0 2
1 2 0
2 0 1
2 1 0
The class permu is a permutation.
You have to overload some operators like ++, –, <<
Hint:
实现前置++, 后置++, 前置–, 后置–, 输出流。
++使当前排列变为字典序比他大一个的排列。例如0 1 2会变成 0 2 1 如果是2 1 0则会变成0 1 2
–使当前排列变为字典序比他小一个的排列。例如2 1 0 会变成2 0 1 如果是0 1 2 则会变成2 1 0
输出流 输出格式为n个数字,每两个数字之间用空格隔开。行末没有空格和换行(换行在main.cpp中已经有了)
法一:直接调用algorithm库的next_permulation和prev_permulation函数
法二,自己写,下面在代码注释中讲解算法:
//在这里写成了一个类 #ifndef PERMU_H #define PERMU_H #include <iostream> #include <vector> #include <queue> using namespace std; class permu { private: vector<int> storage; int len; public: explicit permu(int n); //前置++ permu operator++(); //后置++ permu operator++(int temp); //前置-- permu operator--(); //后置-- permu operator--(int temp); friend ostream& operator<<(ostream& cout, const permu& in); }; permu::permu(int n) { len = n; for (int i = 0; i < n; i++) { storage.push_back(i); } } permu permu::operator++() { // next_permulation 算法 int i, j = 0; // step 1.倒找第一个元素storage[i], 满足 storage[i] < storage[i+1] if (storage[i] < storage[i+1]) { break; } } if (-1 != i) { /*若找到上述i,则逆序找第一个 元素storage[j], 满足storage[j] > storage[i], 然后进行step2. 交换storage[i] 和 storage[j]*/ for (j = len - 1; j >= 0; j--) { if (storage[j] > storage[i]) { break; } } int hold = storage[i]; storage[i] = storage[j]; storage[j] = hold; } /*step 3. 将storage[i+1]到最后一个元素, 逆序就得到所需序列*/ /*若找不到这样i,即i = -1,说明 已没有更大的next_permulation, 直接将所有元素逆序()*/ queue<int> reverse_holder; for (int k = len - 1; k > i; k--) { reverse_holder.push(storage[k]); storage.pop_back(); } while (!reverse_holder.empty()) { storage.push_back(reverse_holder.front()); reverse_holder.pop(); } return *this; } permu permu::operator++(int temp) { permu out = *this; ++(*this); return out; } permu permu::operator--() { // prev_permulation算法 int i, j = 0; for (i = len - 2; i >= 0; i--) { // step 1.倒找第一个元素storage[i],满足 storage[i] > storage[i+1] if (storage[i] > storage[i+1]) { break; } } if (-1 != i) { /*若找到上述i,则逆序找第一个元素storage[j], 满足storage[j] < storage[i], 然后进行step2. 交换storage[i] 和 storage[j]*/ for (j = len - 1; j >= 0; j--) { if (storage[j] < storage[i]) { break; } } int hold = storage[i]; storage[i] = storage[j]; storage[j] = hold; } queue<int> reverse_holder; /*step 3. 将storage[i+1]到最 后一个元素,逆序就得到所需序列*/ /*若找不到这样i,即i = -1,说明已没有 更小的prev_permulation,直接将所有 元素逆序()*/ for (int k = len - 1; k > i; k--) { reverse_holder.push(storage[k]); storage.pop_back(); } while (!reverse_holder.empty()) { storage.push_back(reverse_holder.front()); reverse_holder.pop(); } return *this; } permu permu::operator--(int temp) { permu out = *this; --(*this); return out; } ostream& operator<<(ostream& cout, const permu& in) { int i = 0; for (; i < in.len - 1; i++) { cout << in.storage[i] << ' '; } cout << in.storage[in.len - 1]; return cout; } #endif
相关文章推荐
- 书评:《算法之美( Algorithms to Live By )》
- 动易2006序列号破解算法公布
- Ruby实现的矩阵连乘算法
- C#插入法排序算法实例分析
- 超大数据量存储常用数据库分表分库算法总结
- C#数据结构与算法揭秘二
- C#冒泡法排序算法实例分析
- 算法练习之从String.indexOf的模拟实现开始
- C#算法之关于大牛生小牛的问题
- C#实现的算24点游戏算法实例分析
- c语言实现的带通配符匹配算法
- 浅析STL中的常用算法
- 算法之排列算法与组合算法详解
- C++实现一维向量旋转算法
- Ruby实现的合并排序算法
- C#折半插入排序算法实现方法
- 基于C++实现的各种内部排序算法汇总
- C++线性时间的排序算法分析
- C++实现汉诺塔算法经典实例
- PHP实现克鲁斯卡尔算法实例解析