算法设计与分析全排列问题
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
4
代码实现
int swap(char &a ,char &b) { char temp=a; a=b; b=temp; } 目的: 将数组中对应的两个数交换位置
5
代码实现
void perm(char str[],int k,int m) { int i; if(k==m) //终止条件,表示到最后一个元素了 { ans++;// 全局变量,用来记录全排列的个数 for(i=0;i<=m;i++) printf("%c",str[i]); printf("\n"); return ; } else for(i=k;i<=m;i++) if(ok(str,k,i)) { swap(str[k],str[i]); perm(str,k+1,m); swap(str[k],str[i]); } }
算法概述:
将a[k:m]中的每个元素分别与a[k]中的元素交换,然后递归调用
a[k+1:m]的全排列,并将计算结果做a[0:k]为的后缀。
3
代码实现
int ok(char str[],int a ,int b) { if(b>a) for(int i=a;i<b;i++) if(str[i]==str[b]) return 0; return 1; } 目的: 查看从list[k...i-1]之间是否有与list[i]相等的值,该判断可以消 除重复出现的字符串
12
结果展示
13
谢谢
7
非递归实现
思路:
首先确定序列从小到大排列,然后从后向前找第一对递增序列, 起始位置标记为置换点,其次从序列末开始到置换点之前找第一个比 置换点大的数,并将二者置换,最后将置换点之后的所有数进行逆序, 操作之后的序列为全排列的一个序列。
算法概述:
逆序不变
置换点
1234 --- 12 34 --- 12 3 4 --- 1243 --- 1243
}
}
11
代码实现
完整代码:
void print(int a[],int length) { for(int i=0; i<length; ++i) cout<<a[i]<<" "; cout<<endl; } int main(int argc, char **argv) { int a[4] = {1, 2, 3, 4}; sort(a,a+sizeof(a) / sizeof(int));//预先排序 combination(a, siz源自文库of(a) / sizeof(int)); return 0; }
目的:
将数组a中的下标i到下标j之间的所有元素逆序倒置
10
代码实现
void combination(int a[],int length) { if(length<2) return; while(true) { print(a,length); int i,j; for(i=length-2; i>=0; --i) { //找到第一对递增序列,i标记置换点 if(a[i]<a[i+1]) break; else if(i==0) return; //没有递增序列了,循环结束 } for(j=length-1; j>i; --j) {//找到第一个比标记点大的数 if(a[j]>a[i]) break; } swap(a,i,j); //置换 reverse(a,i+1,length-1); //逆序
1243 --- 1 24 3 --- 1342 --- 1324
逆序操作
8
代码实现
void swap(int *a,int i,int j) { a[i]^=a[j]; a[j]^=a[i]; a[i]^=a[j]; }
目的:
交换数组a中下标为i和j的两个元素的值
9
代码实现
void reverse(int a[],int i,int j) { for(; i<j; ++i,--j) { swap(a,i,j); } }
有重复元素的排列问题
二组
问题描述
• 设R={r1,r2,…,rn}是要进行排列的n个元素,其中r1,r2,…,rn可能相同。试
设计一个算法,列出R的所有不同排列
编程任务
给定以及待排列的个元素。计算出这个元素的所有不同排列
2
递归实现
思路:
运用分治策略,给定一个规模为n的序列,首先解决n-1序列的 排列问题,当n=1时终止,然后返回,最终将所有问题解决。
6
代码实现
完整代码:
int main() { char str[505]; int n,i; scanf("%d",&n);\ getchar(); ans=0; for(i=0;i<n;i++) scanf("%c",&str[i]); perm(str,0,n-1) ; printf("%d\n",ans); return 0; }