相关知识: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中已经有了)
法一:直接调用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