先来复习一下排列组合的知识。
排列组合(组合数学中的一种)permutation and combination 排列的定义及其计算公式
排列有两种定义,但计算方法只有一种,凡是符合这两种定义的都用这种方法计算。定义的前提条件是m≦n,m与n均为自然数。
① 从n个不同元素中,任取m个元素按照一定的顺序排成一列,叫做从n个不同元素中取出m个元素的一个排列。
② 从n个不同元素中,取出m个元素的所有排列的个数,叫做从n个不同元素中取出m个元素的排列数。
③ 用具体的例子来理解上面的定义:4种颜色按不同颜色,进行排列,有多少种排列方法,如果是6种颜色呢。从6种颜色中取出4种进行排列呢。
解:A(4,4)=4x(4-1)x(4-2)x(4-3)x(4-4+1)=4x1x2x3x1=24。
A(6,6)=6x5x4x3x2x1=720。
A(6,4)=6!/(6-4)!=(6x5x4x3x2x1)/2=360。
排列用符号A(n,m)表示,m≦n。
计算公式是:A(n,m)=n(n-1)(n-2)……(n-m+1)=n!/(n-m)!
此外规定0!=1,n!表示n(n-1)(n-2)…1
例如:6!=6x5x4x3x2x1=720,4!=4x3x2x1=24。
组合的定义及其计算公式 组合的定义有两种。定义的前提条件是m≦n。
① 从n个不同元素中,任取m个元素并成一组,叫做从n个不同元素中取出m个元素的一个组合。
② 从n个不同元素中,取出m个元素的所有组合的个数,叫做从n个不同元素中取出m个元素的组合数。
③ 用例子来理解定义:从4种颜色中,取出2种颜色,能形成多少种组合。
解:C(4,2)=A(4,2)/2!={[4x(4-1)x(4-2)x(4-3)x(4-4+1)]/[2x(2-1)x(2-2+1)]}/[2x(2-1)x(2-2+1)]=[(4x3x2x1)/2]/2=6。
函数原型:
template<class BidirectionalIterator>
bool next_permutation(
BidirectionalIterator _First,
BidirectionalIterator _Last
);
template<class BidirectionalIterator, class Compare>
bool next_permutation(
BidirectionalIterator _First,
BidirectionalIterator _Last,
Compare _Comp
);
next_permutation,重新排列范围内的元素[第一,最后一个),返回安装字典序排列的下一个值较大的组合
返回值:如果有一个更高的排列,它重新排列元素,并返回true;如果这是不可能的(因为它已经在最大可能的排列),它安装升序排列重新元素,并返回false。
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
int main()
{
int elements[] = { 1, 2, 3, 4 };
const size_t N = sizeof(elements)/sizeof(elements[0]);
std::vector<int> vec(elements, elements + N);
int count = 0;
do
{
std::cout << ++count << ": ";
std::copy(vec.begin(), vec.end(),
std::ostream_iterator<int>(std::cout, ", "));
std::cout << std::endl;
} while (next_permutation(vec.begin(), vec.end()));
}