STL next_permutation() 函数的返回值探析

【问题描述】
STL next_permutation() 函数,常用于输出给定序列的全排列。但由于对STL next_permutation() 函数的返回值不明晰,导致一些朋友在解读使用STL next_permutation() 函数的代码时,存在困惑。例如,下方代码一、代码二的运行结果,不少朋友就有疑问。
(1)代码一

#include <bits/stdc++.h>
using namespace std;
 
const int maxn=100;
int a[maxn];
int n;
 
int main() {
	cin>>n;
	for(int i=0; i<n; i++) cin>>a[i];
	sort(a,a+n);
	do {
		for(int i=0; i<n; i++)
			cout<<a[i]<<" ";
		cout<<endl;
	} while(next_permutation(a,a+n));
	
	return 0;
}
 
/*
in:
3
1 3 2
out:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
*/

(2)代码二

#include <bits/stdc++.h>
using namespace std;
 
const int maxn=10010;
int a[maxn];
 
int main() {
	int n,m;
	cin>>n>>m;
 
	for(int i=0; i<n; i++)
		cin>>a[i];
		
	for(int i=0; i<m; i++)
		next_permutation(a,a+n);
	
	for(int i=0; i<n-1; i++) {
		cout<<a[i]<<" ";
	}
	cout<<a[n-1];
	
	return 0;
}
 
 
 
/*
in:
5
3
1 2 3 4 5
out:
1 2 4 5 3
*/
 

【STL next_permutation() 函数的返回值探析】
为了解决困惑,必须明确知道STL next_permutation() 函数的返回值。准确地讲,若以某个序列作为STL next_permutation() 函数的参数时(如代码一中的next_permutation(a,a+n)),则每调用一次STL next_permutation() 函数,将得到当前序列按字典序的下一个序列。但是,STL next_permutation() 函数的返回值为true或false。因此,常将STL next_permutation() 函数作为while循环的判断条件。但什么时候返回true,什么时候返回false呢。这可由STL next_permutation() 函数的官方文档 next_permutation - C++ Reference 易知。即:true if the function could rearrange the object as a lexicographicaly greater permutation. Otherwise, the function returns false to indicate that the arrangement is not greater than the previous, but the lowest possible (sorted in ascending order).

为了用中文更清晰地说明此英文表述,以下方实例进行说明。
若给定三个数1,2,3,则它们的全排列按字典序分别为(123),(132),(213),(231),(312),(321)。若将它们抽象为6个结点,可绘制如下示意图。

则若将任意一个结点所示的序列值作为next_permutation() 函数的参数时,将得到按箭头指示的下一个结点的排列。例如:
若当前序列为(132)时,则调用一次next_permutation() 函数后,得到(213)。由于值递增,则此时next_permutation() 函数的返回值为true
若当前序列为(321)时,则调用一次next_permutation() 函数后,得到(123)。由于值递减,则此时next_permutation() 函数的返回值为false

有了上面的解析,就不难理解代码一、代码二的运行结果了。


【参考文献】
https://blog.csdn.net/hnjzsyjyj/article/details/125793169
https://blog.csdn.net/qq_45914558/article/details/107558886

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值