c++全排列 next_permutation()函数

c++全排列

转载博客:https://www.cnblogs.com/cstdio1/p/11311500.html

对于next_permutation函数,其函数原型为:
#include < algorithm>
bool next_permutation(iterator start,iterator end)
当当前序列不存在下一个排列时,函数返回false,否则返回true

同时,相对应的,上一个排列即为prev_permutation(int *begin, int end)
看如下代码:

#include <iostream>  
#include <algorithm>  
using namespace std;  
int main()  
{  
    int num[3]={1,2,3};  
    do  
    {  
        cout<<num[0]<<" "<<num[1]<<" "<<num[2]<<endl;  
    }while(next_permutation(num,num+3));  
    return 0;  
}

在这里插入图片描述
注意:当我们把while(next_permutation(num,num+3))中的3改为2时,输出就变为了下图所示:
在这里插入图片描述
说明此时只针对1,2进行了全排列,有两个,后面的3没有变化,同时改变了数组前两个的值。

由此可以看出,next_permutation(num,num+n)函数是对数组num中的前n个元素进行全排列,同时并改变num数组的值。

另外,需要强调的是,next_permutation()在使用前需要对欲排列数组按升序排序,否则只能找出该序列之后的全排列数。

比如,如果数组num初始化为3,1,2,那么输出就变为了:
在这里插入图片描述

维基百科上全排列的实现:

循环法:

#include <iostream>
using namespace std;
bool arrsame(int* arr, int len, int num) {
    int i;
    for (i = 0; i < len; i++)
        if (arr[i] == num)
            break;
    return i != len;
}
bool next_perm(int* perm, const int k, const int n) {
    int i = k - 1;
    do
        perm[i]++;
    while (arrsame(perm, i, perm[i]) || (perm[i] >= n && i--));
    if (perm[0] >= n)
        return 0;
    for (int num = 0, seat = i + 1; seat < k; num++)
        if (!arrsame(perm, i + 1, num))
            perm[seat++] = num;
    return 1;
}
int main() {
    int n, k;
    cout << "perm(n,k):" << endl;
    cin >> n >> k;
    if (n < k || k <= 0)
        return 0;
    int* perm = new int[k];
    for (int i = 0; i < k; i++)
        perm[i] = i;
    do
        for (int i = 0; i < k; cout << ((++i < k) ? ',' : '\n'))
            cout << perm[i] + 1;
    while (next_perm(perm, k, n));
    delete[] perm;
    return 0;
}

递归法:

#include <bits/stdc++.h>
using namespace std;

struct prem {
    int len;
    vector<int> used, position;
    function<void(vector<int>&)> action;
    prem(int l = 0, function<void(vector<int>&)> a = [](vector<int>& position) {}) : len(l), used(l, -1), position(l), action(a) {}
    void run(int now = -1) {
        if (now == len - 1) {
            action(position);
            return;
        }
        int next = now + 1;
        for (int i = 0; i < len; i++) {
            if (used[i] == -1) {
                used[i] = next;
                position[next] = i;
                run(next);
                used[i] = -1;
            }
        }
    }
};
int main() {
    ios::sync_with_stdio(false), cin.tie(0);
    int len = 4;
    prem p(len, [&](vector<int>& p) {
        for (int i = 0; i < len; i++) {
            cout << p[i] << " ";
        }
        cout << endl;
    });
    p.run();
    return 0;
}

next_permutation 可以自定义比较函数 例如:POJ 1256
题目中要求的字典序是:A’<‘a’<‘B’<‘b’<…<‘Z’<‘z’,所以在用函数之前必须得按照题目要求的进行排序

#include<iostream> //poj 1256 Anagram
#include<string.h>
#include<algorithm>
using namespace std;
int cmp(char a,char b) {
	if(tolower(a)!=tolower(b))//tolower 是将大写字母转化为小写字母.
		return tolower(a)<tolower(b);
	else
		return a<b;
}
int main() {
	char ch[20];
	int n;
	cin>>n;
	while(n--) {
		scanf("%s",ch);
		sort(ch,ch+strlen(ch),cmp);
		do {
			printf("%s\n",ch);
		} while(next_permutation(ch,ch+strlen(ch),cmp));
	}
	return 0;
}
  • 5
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: C++中的next_permutation函数是一个STL算法,用于生成下一个排列。它接受两个迭代器作为参数,表示一个范围内的元素。函数会将这个范围内的元素重新排列,生成下一个排列,并返回true。如果已经是最后一个排列,则返回false。 ### 回答2: C++标准库中的next_permutation函数用于生成一个序列中下一个排列的序列。 该函数在一个非递减排列的序列中,找到下一个比当前排列更大的排列,并对原序列进行重排,如果不存在下一个更大的排列,则返回false。重排完成后,原序列将变为下一个更大的排列。 next_permutation函数接收两个迭代器,表示序列的开始和结束位置。使用该函数时,要求序列必须是允许重复元素的。函数会根据序列中的元素值进行重排。 函数的使用步骤如下: 1. 首先需要包含<algorithm>头文件。 2. 调用next_permutation函数并传入序列的开始和结束迭代器。 3. 函数会返回一个布尔值,表示是否存在下一个更大的排列。 4. 如果返回true,表示存在下一个更大的排列,可以通过迭代器遍历并打印出来。 5. 如果返回false,表示已经是最大排列,序列不再改变。 下面是一个示例代码段,展示了如何使用next_permutation函数: ```cpp #include <iostream> #include <algorithm> #include <vector> int main() { std::vector<int> nums = {1, 2, 3}; // 打印初始排列 for (int num : nums) { std::cout << num << " "; } std::cout << std::endl; // 获取下一个更大的排列 while (std::next_permutation(nums.begin(), nums.end())) { // 打印下一个更大的排列 for (int num : nums) { std::cout << num << " "; } std::cout << std::endl; } return 0; } ``` 运行以上代码,会输出以下结果: 1 2 3 1 3 2 2 1 3 2 3 1 3 1 2 3 2 1 可以看到,函数通过改变序列中元素的排列顺序,依次生成了下一个更大的排列。 ### 回答3: next_permutation函数C++中的一个算法函数,用于获取给定排列的下一个排列。该函数接受两个迭代器作为参数,并在原地将排列重新排列为下一个排列。如果存在下一个排列,则该函数返回true,否则返回false。 next_permutation函数的算法原理是,从后往前找到第一个非递增的元素,记为i。然后再从后往前找到第一个大于i的元素,记为j。将i和j交换位置,并将i之后的元素按照升序重新排列,即得到下一个排列。 下面以一个例子来说明next_permutation函数的使用。假设有一个排列{1, 2, 3},我们使用next_permutation函数来获取所有的排列。 首先,初始排列是{1, 2, 3},然后调用next_permutation函数,它会返回true,并将排列修改为{1, 3, 2}。接着再次调用next_permutation函数,会得到{2, 1, 3},再次调用则得到{2, 3, 1},继续调用则得到{3, 1, 2},最后再次调用则得到{3, 2, 1},此时函数返回false,表示已经获取到了所有的排列。 总结来说,next_permutation函数是用于获取给定排列的下一个排列的函数,通过不断调用该函数,可以获取排列集合中的所有排列。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值