C++ STL 全排列函数详解
一、概念
从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列。当m=n时所有的排列情况叫全排列。如果这组数有n个,那么全排列数为n!个。
比如a,b,c的全排列一共有3!= 6 种 分别是{a, b, c}、{a, c, b}、{b, a, c}、{b, c, a}、{c, a, b}、{c, b, a}。
二、常用操作
1.头文件
#include <algorithm>
2.使用方法
这里先说两个概念:“下一个排列组合”和“上一个排列组合”,对序列 {a, b, c},每一个元素都比后面的小,按照字典序列,固定a之后,a比bc都小,c比b大,它的下一个序列即为{a, c, b},而{a, c, b}的上一个序列即为{a, b, c},同理可以推出所有的六个序列为:{a, b, c}、{a, c, b}、{b, a, c}、{b, c, a}、{c, a, b}、{c, b, a},其中{a, b, c}没有上一个元素,{c, b, a}没有下一个元素。
1)next_permutation:求下一个排列组合
a.函数模板:next_permutation(arr, arr+size);
b.参数说明:
arr: 数组名
size:数组元素个数
c.函数功能: 返回值为bool类型,当当前序列不存在下一个排列时,函数返回false,否则返回true,排列好的数在数组中存储
d.注意:在使用前需要对欲排列数组按升序排序,否则只能找出该序列之后的全排列数。
比如,如果数组num初始化为2,3,1,那么输出就变为了:{2 3 1} {3 1 2} {3 2 1}
2)prev_permutation:求上一个排列组合
a.函数模板:prev_permutation(arr, arr+size);
b.参数说明:
arr: 数组名
size:数组元素个数
c.函数功能: 返回值为bool类型,当当前序列不存在上一个排列时,函数返回false,否则返回true
d.注意:在使用前需要对欲排列数组按降序排序,否则只能找出该序列之后的全排列数。
三、代码
#include <iostream>
#include <algorithm>
using namespace std;
int main ()
{
int arr[] = {,,};
cout<<"用prev_permutation对3 2 1的全排列"<<endl;
do
{
cout << arr[] << ' ' << arr[] << ' ' << arr[]<<'\n';
}
while ( prev_permutation(arr,arr+) ); ///获取上一个较大字典序排列,如果3改为2,只对前两个数全排列 int arr1[] = {,,};
cout<<"用next_permutation对1 2 3的全排列"<<endl;
do
{
cout << arr1[] << ' ' << arr1[] << ' ' << arr1[] <<'\n';
}
while ( next_permutation(arr1,arr1+) ); ///获取下一个较大字典序排列,如果3改为2,只对前两个数全排列
///注意数组顺序,必要时要对数组先进行排序 return ;
}
四、全排列递归思路

public class hello {
public static int arr[] = new int[]{,,};
public static void main(String[] args) {
perm(arr,,arr.length-);
}
private static void swap(int i1, int i2) {
int temp = arr[i2];
arr[i2] = arr[i1];
arr[i1] = temp;
}
/**
* 对arr数组中的begin~end进行全排列
*
* 比如:
* arr = {1,2,3}
* 第一步:执行 perm({1,2,3},0,2),begin=0,end=2;
* j=0,因此执行perm({1,2,3},1,2),begin=1,end=2;
* j=1,swap(arr,0,0)-->arr={1,2,3}, perm({1,2,3},2,2),begin=2,end=2;
* 因为begin==end,因此输出数组{1,2,3}
* swap(arr,1,1) --> arr={1,2,3};
* j=2,swap(arr,1,2)-->arr={1,3,2}, perm({1,3,2},2,2),begin=2,end=2;
* 因为begin==end,因此输出数组{1,3,2}
* swap(arr,2,1) --> arr={1,2,3};
* j=1,swap(arr,0,1) --> arr={2,1,3}, perm({2,1,3},1,2),begin=1,end=2;
* j=1,swap(arr,1,1)-->arr={2,1,3} perm({2,1,3},2,2),begin=2,end=2;
* 因为begin==end,因此输出数组{2,1,3}
* swap(arr,1,1)--> arr={2,1,3};
* j=2,swap(arr,1,2)后 arr={2,3,1},并执行perm({2,3,1},2,2),begin=2,end=2;
* 因为begin==end,因此输出数组{2,3,1}
* swap(arr,2,1) --> arr={2,1,3};
* swap(arr,1,0) --> arr={1,2,3}
* j=2,swap(arr,2,0) --> arr={3,2,1},执行perm({3,2,1},1,2),begin=1,end=2;
* j=1,swap(arr,1,1) --> arr={3,2,1} , perm({3,2,1},2,2),begin=2,end=2;
* 因为begin==end,因此输出数组{3,2,1}
* swap(arr,1,1) --> arr={3,2,1};
* j=2,swap(arr,2,1) --> arr={3,1,2},并执行perm({2,3,1},2,2),begin=2,end=2;
* 因为begin==end,因此输出数组{3,1,2}
* swap(arr,2,1) --> arr={3,2,1};
* swap(arr,0,2) --> arr={1,2,3}
*
*/
public static void perm(int arr[], int begin,int end) {
if(end==begin){ //一到递归的出口就输出数组,此数组为全排列
for(int i=;i<=end;i++){
System.out.print(arr[i]+" ");
}
System.out.println();
return;
}
else{
for(int j=begin;j<=end;j++){
swap(begin,j); //for循环将begin~end中的每个数放到begin位置中去
perm(arr,begin+,end); //假设begin位置确定,那么对begin+1~end中的数继续递归
swap(begin,j); //换过去后再还原
}
}
}
}
C++ STL 全排列函数详解的更多相关文章
- STL之map与pair与unordered_map常用函数详解
STL之map与pair与unordered_map常用函数详解 一.map的概述 map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称 ...
- C++ STL bitset 容器详解
C++ STL bitset 容器详解 本篇随笔讲解\(C++STL\)中\(bitset\)容器的用法及常见使用技巧. \(bitset\)容器概论 \(bitset\)容器其实就是个\(01\)串 ...
- malloc 与 free函数详解<转载>
malloc和free函数详解 本文介绍malloc和free函数的内容. 在C中,对内存的管理是相当重要.下面开始介绍这两个函数: 一.malloc()和free()的基本概念以及基本用法: 1 ...
- STL bind1st bind2nd详解
STL bind1st bind2nd详解 先不要被吓到,其实这两个配接器很简单.首先,他们都在头文件<functional>中定义.其次,bind就是绑定的意思,而1st就代表fir ...
- NSSearchPathForDirectoriesInDomains函数详解
NSSearchPathForDirectoriesInDomains函数详解 #import "NSString+FilePath.h" @implementation ...
- JavaScript正则表达式详解(二)JavaScript中正则表达式函数详解
二.JavaScript中正则表达式函数详解(exec, test, match, replace, search, split) 1.使用正则表达式的方法去匹配查找字符串 1.1. exec方法详解 ...
- Linux C popen()函数详解
表头文件 #include<stdio.h> 定义函数 FILE * popen( const char * command,const char * type); 函数说明 popen( ...
- kzalloc 函数详解(转载)
用kzalloc申请内存的时候, 效果等同于先是用 kmalloc() 申请空间 , 然后用 memset() 来初始化 ,所有申请的元素都被初始化为 0. view plain /** * kzal ...
- Netsuite Formula > Oracle函数列表速查(PL/SQL单行函数和组函数详解).txt
PL/SQL单行函数和组函数详解 函数是一种有零个或多个参数并且有一个返回值的程序.在SQL中Oracle内建了一系列函数,这些函数都可被称为SQL或PL/SQL语句,函数主要分为两大类: 单行函数 ...
随机推荐
- 【最大流】【CODEVS】1993 草地排水
[算法]网络流-最大流(dinic) [题解]http://www.cnblogs.com/onioncyc/p/6496532.html #include<cstdio> #includ ...
- 推箱子 BFS
[编程题] 推箱子 大家一定玩过“推箱子”这个经典的游戏.具体规则就是在一个N*M的地图上,有1个玩家.1个箱子.1个目的地以及若干障碍,其余是空地.玩家可以往上下左右4个方向移动,但是不能移动出地图 ...
- 爬虫--Scrapy之Downloader Middleware
下载器中间件(Downloader Middleware) 下载器中间件是介于Scrapy的request/response处理的钩子框架. 是用于全局修改Scrapy request和respons ...
- 爬虫实战--基于requests 和 Beautiful的7160美图网爬取图片
import requests import os from bs4 import BeautifulSoup import re # 初始地址 all_url = 'http://www.7160. ...
- 高性能优秀的服务框架-dubbo介绍
先来了解一下这些年架构的变化,下面的故事是我编的.... "传统架构":很多年前,刚学完JavaWeb开发的我凭借一人之力就开发了一个网站,网站 所有的功能和应用都集中在一起,方便 ...
- shell编程===执行shell脚本的四种方法
使用vim创建一个shell文件,命名 hello.sh #!/bin/bash echo "hello shell !" 在linux中进行加载 chmod +x ./hello ...
- nginx与PHP的关系和交互方式【转】
nginx与PHP的关系. 对比, apache和PHP的关系, 将PHP安装成apache的一个功能模块, 导致的结果, 对外只有一个apache程序, PHP并不独立出现, 仅仅是apache的模 ...
- curl 发送请求的时候报错
AWS HTTP error: cURL error 60: SSL certificate problem: unable to get local issuer certificate (see ...
- jQuery常用事件方法详解
目录 jQuery事件 ready(fn)|$(function(){}) jQuery.on() jQuery.click jQuery.data() jQuery.submit() jQuery事 ...
- Spring如何解析Dubbo标签
1. 要了解Dubbo是如何解析标签的,首先要清楚一点就是Spring如何处理自定义标签的,因为Dubbo的标签可以算是Spring自定义标签的一种情况: 2. Spring通过两个接口来解析自定义的 ...