排列组合中的搜索
来源:互联网 发布:来源百度地图大数据 编辑:程序博客网 时间:2024/06/05 09:18
本质是都是树的深搜,只不过是递归的出口条件,输出形式以及递归过程的条件不一样。
1:全排列问题:
输入:3
1 2 4
输出:
1 2 4
1 4 2
2 1 4
2 4 1
4 1 2
4 2 1
参考代码实现:
#include<iostream>#include<stdio.h>using namespace std;#define maxn 15int n;int num[maxn];//输入n个数int used[maxn];//标记num[i]是否使用过int rcd[maxn];//标记每个位置的数void fullSort(int k)//全排列函数{ if(k==n) { for(int i=0;i<n;i++) { printf("%d",rcd[i]); if(i<n-1)printf(" "); } printf("\n"); return; } else { for(int j=0;j<n;j++)//枚举所有的数 { if(!used[j])//若num[i]没有使用过,则标记为已用 { used[j]=1; rcd[k]=num[j];//在k的位置上放上该数 fullSort(k+1);//填写写一个位置 used[j]=0;//回溯,清零标记 } } }}int read_data(){ int i; if(scanf("%d",&n)==EOF) return 0; for(i=0;i<n;i++)scanf("%d",&num[i]); for(i=0;i<n;i++) used[i]=0; return 1;}int main(){ while(read_data())fullSort(0);//从第一位置开始 return 0;}
2:一般组合问题:
输入:4 3
1 2 3 4
输出:1 2 3
1 2 4
1 3 4
2 3 4
参考代码实现:
/*选择组合排列 C(4,3)*/#include<iostream>#include<fstream>using namespace std;#define maxn 15int n,m;int rcd[maxn];int num[maxn];void select_Combination(int k,int p){ if(k==m) { for(int i=0;i<m;i++)//只要填满m个位置就要输出 { printf("%d",rcd[i]); if(i<m-1) printf(" "); } printf("\n"); return; } else { for(int j=p;j<n;j++)//无序,上一次位置是num[p-1],所以这一次位置从num[p],试探填充。不需要标记有没有用过。 { rcd[k]=num[j]; select_Combination(k+1,j+1);//填下一个位置。 } }}int read_data(){ if(scanf("%d%d",&n,&m)==EOF) return 0; for(int i=0;i<n;i++)scanf("%d",&num[i]); return 1;}int main(){ while(read_data())select_Combination(0,0); return 0;}
3:n个数的集合问题(2的n次方-1个情况)
输入: 3
1 2 3
输出:1
1 2
1 2 3
1 3
2
2 3
3
参考代码实现:
/*求n个数所有集合 */#include<iostream>#include<stdio.h>#include<time.h>using namespace std;#define maxn 15int n;int rcd[maxn];int num[maxn];void full_Combination(int k,int p){ int i; for(i=0;i<k;i++)//每次进入递归函数都输出。 { printf("%d",rcd[i]); if(i<k-1) printf(" "); } if(k)printf("\n"); for(i=p;i<n;i++)//循环从p开始,结束条件i>=n; { rcd[k]=num[i];//填写该位置的数。 full_Combination(k+1,i+1);//下个位置 }}int read_data(){ if(scanf("%d",&n)==EOF) return 0; for(int i=0;i<n;i++)scanf("%d",&num[i]); return 1;}int main(){ //int start,end; //start=clock(); while(read_data())full_Combination(0,0); //end=clock(); //cout<<(double)(end-start)/CLOCKS_PER_SEC<<endl; return 0;}
4:不重复排列
输入:3
1 1 2
输出:1 1 2
1 2 1
2 1 1
思路:如果像第一种那样,就会多出1 1 2 ,2 1 1,1 2 1的重复,思想是记录本质不同的数出现的次数,输入的过程要过滤重复的元素。把循环的长度减少到不同元素的个数。
参考代码实现:
#include<iostream>#include<stdio.h>using namespace std;#define maxn 10int n,m;int rcd[maxn];int used[maxn];int num[maxn];void norepeat_Sort(int k){ if(k==n) { for(int i=0;i<n;i++) { printf("%d",rcd[i]); if(i<n-1)printf(" "); } printf("\n"); return; } else { for(int j=0;j<m;j++)//枚举不同元素的个数 { if(used[j]>0)//若num[i]还没用完,继续用这个数填充下个位置。 { used[j]--;//可用次数减少 rcd[k]=num[j]; norepeat_Sort(k+1);//填写下个位置 used[j]++;//可用次数还原 } } }}int read_data(){ int i,j,val; if(scanf("%d",&n)==EOF)return 0; m=0; for(i=0;i<n;i++) { scanf("%d",&val); for(j=0;j<m;j++)//删选不同的元素,并记录每一元素记录的次数。 { if(num[j]==val) { used[j]++; break; } } if(j==m) { num[m]=val; used[m++]=1; } } return 1;}int main(){ while(read_data())norepeat_Sort(0); return 0;}
5:不重复的组合
输入:3
1 1 3
输出:1
1 1
1 1 3
1 3
3
思路:同上(本质一样)
参考代码实现:
#include<iostream>#include<stdio.h>using namespace std;#define maxn 10int n,m;int rcd[maxn];int used[maxn];int num[maxn];void norepeat_Comb(int k,int p){ for(int i=0;i<k;i++)//每次都输出 { printf("%d",rcd[i]); if(i<k-1)printf(" "); } if(k)printf("\n"); for(int j=p;j<m;j++)//从P开始,枚举不同元素的个数 { if(used[j]>0)//若num[i]还没用完,继续用这个数填充下个位置。 { used[j]--;//可用次数减少 rcd[k]=num[j]; norepeat_Comb(k+1,j);//这里从j开始,不是j+1;因为不止一个数、 used[j]++;//可用次数还原 } }}int read_data(){ int i,j,val; if(scanf("%d",&n)==EOF)return 0; m=0; for(i=0;i<n;i++) { scanf("%d",&val); for(j=0;j<m;j++)//删选不同的元素,并记录每一元素记录的次数。 { if(num[j]==val) { used[j]++; break; } } if(j==m) { num[m]=val; used[m++]=1; } } return 1;}int main(){ while(read_data())norepeat_Comb(0,0); return 0;}
- 排列组合中的搜索
- 搜索水题 (排列组合)
- 数学中的排列组合
- java 中的一种排列组合
- SQL排列组合型搜索问题解决方法
- java递归算法中的排列组合问题及排列组合去重
- 排列组合
- 排列组合
- 排列组合
- 排列组合
- 排列组合
- 排列组合
- 排列组合
- 排列组合
- 排列组合
- 排列组合
- 排列组合
- 排列组合
- Android中的Intent filter使用
- 开源框架spring学习之道:事务管理的深刻理解
- HDU 1171 母函数
- 开源框架Spring学习之道:IoC的深刻理解
- 如何在Windows下开发Python:在cmd下运行Python脚本+如何使用Python Shell(command line模式和GUI模式)+如何使用Python IDE
- 排列组合中的搜索
- 开源框架spring学习之道:AOP的深刻理解
- 阿里联手新浪发微博淘宝版 暂停与微信相关应用
- Android UI的前篇
- 关键词工具的看法
- 开源框架Spring学习之道:IoC控制反转(一)
- 30岁以后还做码农一定没有前途
- 波特率
- 关于hibernateTemplate的概念性理解