说明:按着书中的思想敲的,记录一下自己的学习过程,最下面附带刘汝佳源代码。
1)生成1~n的排列(自己写的)
#include<stdio.h>
#include<iostream>
using namespace std;
int n;
void p(int *a,int cur){
if(cur==n){
for(int i=0;i<n;i++)
printf("%d ",a[i]);
printf("\n");
}
else
{
for(int i=1;i<=n;i++){
int ok=1;
for(int j=0;j<cur;j++)
if(a[j]==i) {ok=0;break;}
if(ok){
a[cur]=i;
p(a,cur+1);
}
}
}
}
int main(){
int a[1010];
while(cin >>n){
p(a,0);
}
return 0;
}
2)生成可重集的排列(自己写的)
#include<stdio.h>
int n;
void q(int *p,int *a,int cur){
if(cur==n){
for(int i=0;i<n;i++)
printf("%d ",a[i]);
printf("\n",);
}else for(int i=0;i<n;i++) if(!i || p[i]!=p[i-1]){
int c1=0,c2=0;
for(int j=0;j<cur;j++) if(a[j]==p[i]) c1++;
for(int j=0;j<n;j++) if(p[j]==p[i]) c2++;
if(c1<c2){
a[cur]=p[i];
q(p,a,cur+1);
}
}
}
int main(){
while(~scanf("%d",&n)){
int p[1010],a[1010];
for(int i=0;i<n;i++)
scanf("%d",&p[i]);
q(p,a,0);
}
return 0;
}
3)7.2.4下一个排列(自己敲的)
#include<iostream>
#include<stdio.h>
#include<algorithm>
using namespace std;
int main(){
int p[1010],n;
while(cin>>n){
for(int i=0;i<n;i++){
cin >> p[i];
}
sort(p,p+n);
do{
for(int i=0;i<n;i++)
printf("%d ",p[i]);
cout <<endl;
}while(next_permutation(p,p+n));
}
return 0;
}
下面是从官网下载的刘汝佳源代码:
// 求1~n的全排列. n<100
// Rujia Liu
#include<cstdio>
using namespace std;
int A[101];
// 输出1~n的全排列
void print_permutation(int n, int* A, int cur) {
if(cur == n) { // 递归边界
for(int i = 0; i < n; i++) printf("%d ", A[i]);
printf("\n");
} else for(int i = 1; i <= n; i++) { // 尝试在A[cur]中填各种整数i
int ok = 1;
for(int j = 0; j < cur; j++)
if(A[j] == i) ok = 0; // 如果i已经在A[0]~A[cur-1]出现过,则不能再选
if(ok) {
A[cur] = i;
print_permutation(n, A, cur+1); // 递归调用
}
}
}
int main() {
int n;
scanf("%d", &n);
print_permutation(n, A, 0);
return 0;
}
// 可重集的全排列
// Rujia Liu
#include<cstdio>
#include<algorithm>
using namespace std;
int P[100], A[100];
// 输出数组P中元素的全排列。数组P中可能有重复元素
void print_permutation(int n, int* P, int* A, int cur) {
if(cur == n) {
for(int i = 0; i < n; i++) printf("%d ", A[i]);
printf("\n");
} else for(int i = 0; i < n; i++) if(!i || P[i] != P[i-1]) {
int c1 = 0, c2 = 0;
for(int j = 0; j < cur; j++) if(A[j] == P[i]) c1++;
for(int j = 0; j < n; j++) if(P[i] == P[j]) c2++;
if(c1 < c2) {
A[cur] = P[i];
print_permutation(n, P, A, cur+1);
}
}
}
int main() {
int i, n;
scanf("%d", &n);
for(i = 0; i < n; i++)
scanf("%d", &P[i]);
sort(P, P+n);
print_permutation(n, P, A, 0);
return 0;
}
// 可重集的全排列(next_permutation版)
// Rujia Liu
#include<cstdio>
#include<algorithm>
using namespace std;
int main() {
int n, p[10];
scanf("%d", &n);
for(int i = 0; i < n; i++) scanf("%d", &p[i]);
sort(p, p+n); // 排序,得到p的最小排列
do {
for(int i = 0; i < n; i++) printf("%d ", p[i]); // 输出排列p
printf("\n");
} while(next_permutation(p, p+n)); // 求下一个排列
return 0;
}