STL/next_permutation()和prev_permutation()函数

next_permutation()和prev_permutation()函数的使用:

next_permutation()和prev_permutation()函数的头文件添加为:#include  <algorithm>

算法:

首先,从最为段开始往前寻找两个相邻的元素,令第一个元素索引为 endi 第二个元素索引为 endii ,且满足 array[endi]<array[endii] 。然后,再从最尾端开始向前检测,找到第一个大于 array[endi] 的元素,令其为索引 j 。将元素 array[endi],array[j] 对调,然后将 endii 之后的所有元素颠倒排列。即求的下一个排列。

解释:

一、如果数组 k 以后的是一个递减序列,则仅依靠调换 k 以后的元素不可能完成任务,所以必须找到满足 k>k+1 的元素,即保证 k 以后的序列不递减。

二、满足一之后,那么下一个序列的第 k 位一定是从后面找到刚好比 a[k] 大的一个比 a[k] 大的一个数打头的(为了保证刚好大于,又 k+1 之后的元素递减,所以从数组尾开始找到第一个比 a[k] 大的元素即可满足要求)。将这个数的索引记为 j 。

三、将 a[j] 与 a[k] 对调。此时, j 后面的元素是降序的。所以需要把 j 后面的逆转一下,从降序到升序,如此就得到了恰好比之前序列大一号的序列。

代码:next_permutation

bool nextPermutation(int array[],int len)
{
    int endi=len-1;
    int endii;
    if(len==1)return false;
    while(true)
    {
        endii=endi;
        endi--;
        if(array[endi]<array[endii])// 如果前一个元素小于后一个元素
        {
            int j=len;
            while(array[--j]<array[endi]);// 由尾端往前找,直到遇上比array[endi]大的元素
            swap(array[j],array[endi]);   // 交换找到的元素
            reverse(array+endii,array+len-1);// 将 endii 之后的元素全部逆向重排
            return true;
        }
        if(endi==0)//排列已至最大,无下一个排列
        {
            reverse(array,array+len-1);
            return false;
        }

    }
}
代码:prev_permutation

bool prevPermutation(int array[],int len)
{
    int endi=len-1;
    int endii;
    if(len==1)return false;
    while(true)
    {
        endii=endi;
        endi--;
        if(array[endi]>array[endii])// 如果前一个元素大于后一个元素
        {
            int j=len;
            while(array[--j]>array[endi]);// 由尾端往前找,直到遇上比array[endi]小的元素
            swap(array[j],array[endi]);   // 交换找到的元素
            reverse(array+endii,array+len-1);// 将 endii 之后的元素全部逆向重排
            return true;
        }
        if(endi==0)//排列已至最小,无上一个排列
        {
            reverse(array,array+len-1);
            return false;
        }

    }
}

next_permutation()和perv_permutation()函数的用法:

#include <iostream>  
#include <string>  
#include <algorithm>  
using namespace std;  
  
//next_permutation()全排列的下一个  
//prev_permutation()全排列的前一个,括号中都为数组的起始结束位置的指针  
  
void print_int(int a[], int length) {//这个用来输出数组  
    for (int i = 0; i < length; i++) {  
        cout << a[i] << " ";  
    }  
    cout << "\t";  
}  
  
int main() {  
      
    int t_int1[4] = {1, 2, 3, 4}, t_int2[4] = {4, 3, 2, 1};  
    string t_str1 = "abcd", t_str2 = "dcba";  
      
    cout << "use next_permutation:" << endl << endl;  
    cout << "for int:" << endl << endl;  
      
    print_int(t_int1, 4);  
    while (next_permutation(t_int1, &t_int1[4])) {//当没有下一个时返回false  
        print_int(t_int1, 4);  
    }  
    cout << endl;  
      
    cout << endl << "for str:" << endl << endl;  
    cout << t_str1 << " \t";  
    while (next_permutation(t_str1.begin(), t_str1.end())) {  
        cout << t_str1 << " \t";  
    }  
    cout << endl << endl;  
      
    cout << "use prev_permutation:" << endl << endl;  
    cout << "for int:" << endl << endl;  
      
    print_int(t_int2, 4);  
    while (prev_permutation(t_int2, &t_int2[4])) {//当没有前一个时返回false  
        print_int(t_int1, 4);  
    }  
    cout << endl;  
      
    cout << endl << "for str:" << endl << endl;  
    cout << t_str2 << " \t";  
    while (prev_permutation(t_str2.begin(), t_str2.end())) {  
        cout << t_str2 << " \t";  
    }  
    cout << endl;  
      
      
    return 0;  
}
运行结果:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Gabanon

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值