【问题描述】
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