next_permutation函数

组合数学中经常用到排列,这里介绍一个计算序列全排列的函数:next_permutation(start,end),和prev_permutation(start,end)。这两个函数作用是一样的,区别就在于前者求的是当前排列的下一个排列,后一个求的是当前排列的上一个排列。至于这里的“前一个”和“后一个”,我们可以把它理解为序列的字典序的前后,严格来讲,就是对于当前序列pn,他的下一个序列pn+1满足:不存在另外的序列pm,使pn<pm<pn+1.

对于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[]={,,};
do
{
cout<<num[]<<" "<<num[]<<" "<<num[]<<endl;
}while(next_permutation(num,num+));
return ;
}

运行结果如图:

注意:当我们把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 = ; 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 - ;
do
perm[i]++;
while (arrsame(perm, i, perm[i]) || (perm[i] >= n && i--));
if (perm[] >= n)
return ;
for (int num = , seat = i + ; seat < k; num++)
if (!arrsame(perm, i + , num))
perm[seat++] = num;
return ;
}
int main() {
int n, k;
cout << "perm(n,k):" << endl;
cin >> n >> k;
if (n < k || k <= )
return ;
int* perm = new int[k];
for (int i = ; i < k; i++)
perm[i] = i;
do
for (int i = ; i < k; cout << ((++i < k) ? ',' : '\n'))
cout << perm[i] + ;
while (next_perm(perm, k, n));
delete[] perm;
return ;
}

递归法:

#include <bits/stdc++.h>
using namespace std; struct prem {
int len;
vector<int> used, position;
function<void(vector<int>&)> action;
prem(int l = , function<void(vector<int>&)> a = [](vector<int>& position) {}) : len(l), used(l, -), position(l), action(a) {}
void run(int now = -) {
if (now == len - ) {
action(position);
return;
}
int next = now + ;
for (int i = ; i < len; i++) {
if (used[i] == -) {
used[i] = next;
position[next] = i;
run(next);
used[i] = -;
}
}
}
};
int main() {
ios::sync_with_stdio(false), cin.tie();
int len = ;
prem p(len, [&](vector<int>& p) {
for (int i = ; i < len; i++) {
cout << p[i] << " ";
}
cout << endl;
});
p.run();
return ;
}

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[];
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 ;
}

.

c++中的全排列的更多相关文章

  1. [LeetCode] Permutation in String 字符串中的全排列

    Given two strings s1 and s2, write a function to return true if s2 contains the permutation of s1. I ...

  2. STL中关于全排列next_permutation以及prev_permutation的用法

    这两个函数都包含在algorithm库中.STL提供了两个用来计算排列组合关系的算法,分别是next_permutation和prev_permutation. 一.函数原型 首先我们来看看这两个函数 ...

  3. [LeetCode] 567. Permutation in String 字符串中的全排列

    Given two strings s1 and s2, write a function to return true if s2 contains the permutation of s1. I ...

  4. STL中的全排列实现

    permutation: 在遇到全排列问题时,在数据量较小的情况下可以使用dfs的做法求得全排列,同时我们也知道在STL中存在函数next_permutation和prev_permutation,这 ...

  5. java实现全排列问题

    1.问题描述: 一组字符串的全排列,按照全排列的顺序输出,并且每行结尾无空格. 2.输入: 输入一个字符串 3.输入示例: 请输入全排列的字符串: abc 4.输出示例: a b c a c b b ...

  6. c语言的全排列

    在c语言中实现全排列,对于刚接触c语言,还没学习算法的人来说,比较困难了吧.估计大佬也不会看这种基础的东西,全排列实现的办法很多,在c++中有一个专门的函数可以使用,但是在c中实现就有点困难了.如果你 ...

  7. c语言中一种典型的排列组合算法

    c语言中的全排列算法和组合数算法在实际问题中应用非常之广,但算法有许许多多,而我个人认为方法不必记太多,最好只记熟一种即可,一招鲜亦可吃遍天 全排列: #include<stdio.h> ...

  8. 【C/C++】n皇后问题/全排列/递归/回溯/算法笔记4.3

    按常规,先说一下我自己的理解. 递归中的return常用来作为递归终止的条件,但是对于返回数值的情况,要搞明白它是怎么返回的.递归的方式就是自己调用自己,而在有返回值的函数中,上一层的函数还没执行完就 ...

  9. 2014亚马逊在线笔试题目及解决方案(MMChess问题)

    整体思路:关键是需要知道当前Steps数组中的全排列即可,而且需要不重复的全排列.即关键在于非递归的全排列实现即可~ 其实直接利用STL中的next_permutation算法的,这里我又自己实现了一 ...

随机推荐

  1. JDBC通过资源文件初始化

  2. !important面试汇总啊

    https://www.jianshu.com/p/feab89b88d6b https://juejin.im/post/5c64d15d6fb9a049d37f9c20#heading-57

  3. window照片查看器无法查看照片的问题

    查看其他照片都可以,只有特殊的两张无法查看.百度|| 修改了环境变量中的tmp变量,路径改为e:\tmp(注:要选择磁盘空间足够的磁盘). 刷新过后,重新打开同一张图片,如下: 用系统自带画图软件尝试 ...

  4. lc 0226

    目录 ✅ 232. 用栈实现队列 描述 解答 c py ✅ 496. 下一个更大元素 I 描述 解答 java another java ✅ 232. 用栈实现队列 https://leetcode- ...

  5. leetcode 0208

    目录 ✅ 108. 将有序数组转换为二叉搜索树 描述 解答 py [tdo rev 0208]py知识:if not x: 和if x is not None:和if not x is None:使用 ...

  6. BGR 与 HSV 模式的转换规则

    HSV模式中的H.S.V分别表示色调.饱和度.亮度 RGB转化到HSV的算法:max=max(R,G,B) min=min(R,G,B) if R = max, H = (G-B)/(max-min) ...

  7. 【网摘】将图片地址直接 转为 base64

    $(function() { function getBase64Image(img) { //转换为 base64 地址 var canvas = document.createElement(&q ...

  8. Js判断值是否是NaN

    方法一:window.isNaN() 注意: window.isNaN 只对数值有效,如果传入其他值,会被先转成数值.比如,传入字符串的时候,字符串会被先转成NaN,所以最后返回true,这一点要特别 ...

  9. Activiti工作流数据库表结构

    Activiti工作流引擎数据库表结构 数据库表的命名 Acitiviti数据库中表的命名都是以ACT_开头的.第二部分是一个两个字符用例表的标识.此用例大体与服务API是匹配的. ACT_RE_*: ...

  10. idea 控制台中文乱码 解决方法

    添加 -Dfile.encoding=UTF-8