生成1~n的排列:
输入整数n,按字典序从小到大的顺序输出前n个数的所有排列。生成1~n的排列可以通过递归思想解决!
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
const int Max = 100000 + 10;
int mem[Max];
void solve(int n, int *a, int num)
{
if(num == n)///递归边界
{
for(int i = 0; i < n - 1; i++)
printf("%d ",a[i]);
printf("%d\n",a[n-1]);
}
else
{
for(int i = 1; i <= n; i++)///在a[num]中遍历一遍所有数
{
int ok = 0;
for(int j = 0; j < num; j++)
{
if(a[j] == i)///判断a[0]~a[num-1]是否出现过该数字,出现标记为1
ok = 1;
}
if(!ok)
{
a[num] = i;
solve(n,a,num+1);
}
}
}
return;
}
int main()
{
int n;
while (~scanf("%d",&n))
{
solve(n,mem,0);
}
return 0;
}
输入数组q,并按字典序从小到大的顺序输出数组a各元素的所有全排列。生成可重集的排列同样是通过递归思想解想,需注意排列没有遗漏和重复!
#include <bits/stdc++.h>
using namespace std;
const int Max = 100000 + 10;
int mem[Max], q[Max];
void solve(int n, int *p, int *a, int num)
{
if(num == n)///递归边界
{
for(int i = 0; i < n - 1; i++)
printf("%d ",a[i]);
printf("%d\n",a[n-1]);
}
else
{
for(int i = 0; i < n; i++)///在a[num]中遍历一遍p数组中所有的数
{
int bj1 = 0, bj2 = 0;
if(!i || p[i] != p[i-1])///避免重复
{
for(int j = 0; j < num; j++) if(a[j] == p[i]) bj1++;///统计a[0]~a[num-1]中p[i]的出现次数bj1;
for(int j = 0; j < n; j++) if(p[i] == p[j]) bj2++;///统计p数组中p[i]的出现次数bj2;
if(bj1 < bj2)///避免遗漏
{
a[num] = p[i];
solve(n,p,a,num+1);
}
}
}
}
return;
}
int main()
{
int n;
while (~scanf("%d",&n))
{
for(int i = 0; i < n; i++)
scanf("%d",&q[i]);
sort(q,q+n);
solve(n,q,mem,0);
}
return 0;
}
除了上述的用递归来解决两个问题外,还可以用STL自带函数next_permutation来解决生成1 ~ n的排列、生成可重集的排列两个问题!next_permutation(mem,mem+n)表示对mem数组的mem[0] ~ mem[n]之间的数字按字典序进行排列!
#include <algorithm>
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <math.h>
using namespace std;
const int Max = 100000 + 10;
int n, mem[Max];
void solve_int()///int 类型的 next_permutation 使用
{
for(int i = 0; i < n; i++)
scanf("%d",&mem[i]);
sort(mem,mem+n);
do
{
for(int i = 0; i < n - 1; i++)
printf("%d ",mem[i]);
printf("%d\n",mem[n-1]);
}while(next_permutation(mem,mem+n));
}
void solve_char()///char 类型的 next_permutation 使用
{
int len;
char ch[Max];
scanf("%s",ch);
len = strlen(ch);
sort(ch,ch+len);
do
{
printf("%s\n",ch);
}while(next_permutation(ch,ch+len));
}
void solve_string()///string 类型的 next_permutation 使用
{
string str;
while(cin >> str && str != "*")
{
sort(str.begin(),str.end());
do
{
cout << str << endl;
}
while(next_permutation(str.begin(),str.end()));
}
}
bool cmp(char a, char b)///自定义排序顺序,'A' < 'a' < 'B' < 'b' ... < 'Z' < 'z'
{
if(tolower(a) == tolower(b))
return a < b;
else
return tolower(a) < tolower(b);
}
void solve_mem()///自定义排序方法后 next_permutation 的使用
{
int len;
char ch[Max];
scanf("%s",ch);
len = strlen(ch);
sort(ch,ch+len,cmp);
do
{
printf("%s\n",ch);
}while(next_permutation(ch,ch+len,cmp));
}
int main ()
{
scanf("%d", &n);
solve_int();
solve_char();
solve_string();
solve_mem();
return 0;
}