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. ln N! -> N(lnN -1)

  2. 【代码审计】MenInfo文件包含漏洞

    代码审计是我之前一直不敢涉及的领域,它包含的知识面太广.最近才开始学习,前段时间写的第一篇代码审计的文章 更多的感觉像是一个黑盒测试.我也会尽量把文章写的通俗易懂.代码审计 0基础从大牛的蜕变 从这里 ...

  3. hadoop StandAlone环境搭建

    1.准备一台服务器 192.168.100.100 2.提前安装jdk 3.hadoop运行服务 NameNode            192.168.100.100 SecondaryNameNo ...

  4. 【PAT甲级】1064 Complete Binary Search Tree (30 分)

    题意:输入一个正整数N(<=1000),接着输入N个非负整数(<=2000),输出完全二叉树的层次遍历. AAAAAccepted code: #define HAVE_STRUCT_TI ...

  5. 洛谷 P5057 [CQOI2006]简单题(树状数组)

    嗯... 题目链接:https://www.luogu.org/problem/P5057 首先发现这道题中只有0和1,所以肯定与二进制有关.然后发现这道题需要支持区间更改和单点查询操作,所以首先想到 ...

  6. 类似discuz密码的生成规则

    /* 生成一个串,uniqid(rand()): uniqid(prefix,more_entropy) 函数基于以微秒计的当前时间,生成一个唯一的 ID. 如果 prefix 参数为空,则返回的字符 ...

  7. iOS项目开发日常之创建文件(协议、类、分类、扩展)

    iOS项目开发过程中,是以不断创建文件的形式进行着的. 创建得比较频繁的文件类型是: 这两个类型中创建的文件有:子类.分类.扩展.协议四种文件,如下:    这四类文件是频繁创建的,我们来看一下各自分 ...

  8. [转]No configuration found for the specified action 原因及解决方案

    转自 报错内容 警告: No configuration found for the specified action: 'login' in namespace: ''. Form action d ...

  9. 3_05_MSSQL课程_Ado.Net_DataSet数据集

    //创建一个内存的数据集 DataSet ds=new DataSet("LJK"); //创建一张内存表 DataTable dt01=new DataTable("d ...

  10. css样式和定义的class都没问题,但样式却没生效

    今天开发遇到过这样的问题,主要原因是 css 文件格式有问题导致的.有问题的 css 样式的那一行下面的 css 样式不能生效