您的位置:首页 > 编程语言 > C语言/C++

C++中next_permutation的实现

2010-07-16 10:24 260 查看
在做算法题目的时候,我们经常会遇到穷举一个集合的所有全排列的情况,最常用的方法是用递归的方式来实现。代码如下所示,
void permutation(int l, int n)
{
if(l >= n)
{
for(int i = 0; i < n; i++)
{
cout << output[i] << " ";
}
cout << endl;
return ;
}

for(int i = 0; i < n; i ++)
{
if(visited[i])
{
output[l] = input[i];
visited[i] = 0;
permutation(l+1, n);
visited[i] = 1;
}
}

}


这是用递归的方法实现的。这个方法的缺点在于不能排除重复的排列,比如{1, 1, 2, 3}这个集合,排列数应该是12,但是按照上述方法就会弄出24种排列,其中的12种都是重复的。原因是这个求全排列的方法是根据数组下标来进行排列的,并没有考虑到元素之间实际的大小关系。而使用next_permutation就能很好地解决这个问题,这跟next_permutation的实现方法有关,下面详细介绍next_permutation的实现过程。

首先,执行next_permutation的集合一定要是有序的,并且是从小到大的顺序,如果无序,则先排序。从最后一个元素last开始依次向前面检查,每次都只检查相邻的元素,如果发现某一对元素右边的数比左边大,则对左边的数也就是较小的数做一个标记,表明它是要被交换的元素,然后,接着从最右边last的位置开始找,直到找到一个比标记元素大的元素,使之和标记元素交换,然后对标记后面的所有元素进行反转,就这样一直执行,直到程序结束。

next_permutation有很多优点,第一个优点是不会列举出重复的全排列。第二个优点是next_permutation不仅可以求排列,还可以求组合,比如要求4个元素的2组合(4个元素任意选出2个元素的所有可能),我们可以建立一个4个元素的数组,分别存放元素0011,然后对这个数组用next_permutation进行求排列,排列出的所有结果都是数组的下标,其中0表示不存在,1表示存在。取出下标对应的元素,即得到所有组合。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: