permulation and review

2 篇文章 0 订阅

相关知识: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_permulationprev_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
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值