您的位置:首页 > 其它

7.2枚举排列

2016-04-21 18:51 323 查看
7.2.1生成1~n 的排列问题描述:输入整数N,按照字典序从小到大打印出1-N的去所有排列。两个序列的字典序大小关系等价于从头开始第一个不相同处的大小关系,(例如(1,2,3)<(3,2,1)),N=3时,输出结果是:(1,2,3)(1,3,2)(2,1,3)(2,3,1)(3,1,2)(3,2,1). 算法思想:设集合S是保持带排列元素的集合,数组A保持排列的元素。如果集合S为空,则表示完成了一个排列,不再继续递归,否则将S中的元素V加入到A中,且S = S-{V},继续递归寻找下一个可以加入到排列中的元素。
#include<iostream>
using namespace std;
void print_permutation(int n, int *A, int cur)
{
int i, j;
if (cur == n)//递归边界
{
for (i = 0; i < n; i++)
cout << A[i];
cout << endl;
}
else for (i = 1; i <= n; i++)//尝试在A[cur]中添各种整数
{
int ok = 1;
for (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, A[100], cur = 0;
cout << "输入小于100的整数" << endl;
while (cin >> n)
{
for (int i = 0; i<n; i++){
A[i] = i + 1;
}
print_permutation(n, A, cur);
}
return 0;
}

7.2.2生成可重集的排列上面求排列的程序只适用于任意两个元素均不相同的序列,如果要求有元素相同的序列的排列时,则需要对上面的程序进行修改。
#include<iostream>
#include<algorithm>
using namespace std;
void print(int n,int*p,int *A,int cur)//p只是把地址传过来了
{
int i, j;
if (cur == n)
{
for (i = 0; i < n; i++)
{
cout << A[i];
}
cout << endl;
}
else for (i = 0; i <n; i++)
if(!i||p[i] != p[i - 1]) //只需检查P的第一个元素和所有与前面不一样的元素即可
{
int c1=0,c2=0;
for (j = 0; j < cur; j++)
if (A[j] == p[i])c1++;
for (j = 0; j < n;j++)
if (p[j] == p[i])c2++;
if (c1<c2)
{
A[cur] =p[i];
print(n, p,A, cur + 1);
}
}
}
int main()
{
int n,i, A[100],cur=0; int p[100];
while (cin >> n)
{
for ( i = 0; i < n; i++)
{
cin >> p[i];
}
sort(p, p + n);
print(n, p,A,cur);
}
return 0;
}
7.2.3解答树!7.2.4 下一个排列枚举所有排列的另一个方法是从字典序最小的排列开始,不停调用“求下一个排列”的过程。           如何求下一个排列呢?C++的STL中提供了一个库函数next_permutation。用next_permutation和prev_permutation求排列组合很方便,但是要记得包含头文件#include <algorithm>。        虽然最后一个排列没有下一个排列,用next_permutation会返回false,但是使用了这个方法后,序列会变成字典序列的第一个,如cba变成abc。prev_permutation同理。
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
int n, p[100];
cin >> n;
for (int i = 0; i < n; i++)
cin >> p[i];
sort(p, p + n);
do
{
for (int i = 0; i < n; i++)
cout << p[i];
cout << endl;
} while (next_permutation(p, p + n));
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: