生成排列和组合

部署运行你感兴趣的模型镜像

1 . 无重复元素的全排列

当然stl有next_permutation()函数,用起来更方便

#include<cstdio>
#include<string>
using namespace std;
int n,a[100],count;
void permutation(int k){
	if(k==n){
		for(int i=1;i<=n;i++)
			printf("%d ",a[i]);
		printf("\n");
		count++;
		return;
	}
	for(int i=k;i<=n;i++){
		int tem=a[k];
		a[k]=a[i];
		a[i]=tem;
		permutation(k+1);
		tem=a[k];
		a[k]=a[i];
		a[i]=tem;
	}
}
int main(){
	while(scanf("%d",&n)!=EOF){
		for(int i=1;i<=n;i++)
			a[i]=i;
			//scanf("%d",&a[i]);
		count=0;
		permutation(1);
		printf("There is %d permutatiomns\n",count);
	}
}

2 . 有重复元素的全排列

 

#include<cstdio>
#include<string>
#include<map>
using namespace std;
int n,m,seq[100],sum[100],count,out[100];          //n表示输入字符数,m表示不重复字符数
void permutation(int k){
	if(k==n+1){
		for(int i=1;i<=n;i++)
			printf("%d ",out[i]);
		printf("\n");
		count++;
		return;
	}
	for(int i=1;i<=m;i++)
		if(sum[i]){
			sum[i]--;
			out[k]=seq[i];
			permutation(k+1);
			sum[i]++;
		}
}
int main(){
	int tem;
	while(scanf("%d",&n)!=EOF){
		map<int,int>ma;
		m=0;
		memset(sum,0,sizeof(sum));
		for(int i=1;i<=n;i++){
			scanf("%d",&tem);
			if(ma[tem]!=0)
				sum[ma[tem]]++;
			else{
				seq[++m]=tem;
				sum[m]=1;
				ma[tem]=m;
			}
		}
		count=0;
		permutation(1);
		printf("There is %d permutatiomns\n",count);
	}
}


 3 . 有重复元素的组合

#include<cstdio>
#include<string>
#include<map>
using namespace std;
int n,k,m,seq[100],sum[100],count,out[100];          //n表示输入字符数,m表示不重复字符数
void combination(int now,int p){
	if(now==k+1){
		for(int i=1;i<=k;i++)
			printf("%d ",out[i]);
		printf("\n");
		count++;
		return;
	}
	for(int i=p;i<=m;i++)
		if(sum[i]){
			sum[i]--;
			out[now]=seq[i];
			combination(now+1,i);
			sum[i]++;
		}
}
int main(){
	int tem;
	while(scanf("%d %d",&n,&k)!=EOF){
		map<int,int>ma;
		m=0;
		memset(sum,0,sizeof(sum));
		for(int i=1;i<=n;i++){
			scanf("%d",&tem);
			if(ma[tem]!=0)
				sum[ma[tem]]++;
			else{
				seq[++m]=tem;
				sum[m]=1;
				ma[tem]=m;
			}
		}
		count=0;
		combination(1,1);
		printf("There is %d combinations\n",count);
	}
}


 4 . 有重复元素的全组合

#include<cstdio>
#include<string>
#include<map>
using namespace std;
int n,k,m,seq[100],sum[100],count,out[100];          //n表示输入字符数,m表示不重复字符数
void combination(int now,int p){
	if(now>1){
		for(int i=1;i<now;i++)
			printf("%d ",out[i]);
		printf("\n");
		count++;
	}
	for(int i=p;i<=m;i++)
		if(sum[i]){
			sum[i]--;
			out[now]=seq[i];
			combination(now+1,i);
			sum[i]++;
		}
}
int main(){
	int tem;
	while(scanf("%d",&n)!=EOF){
		map<int,int>ma;
		m=0;
		memset(sum,0,sizeof(sum));
		for(int i=1;i<=n;i++){
			scanf("%d",&tem);
			if(ma[tem]!=0)
				sum[ma[tem]]++;
			else{
				seq[++m]=tem;
				sum[m]=1;
				ma[tem]=m;
			}
		}
		count=0;
		combination(1,1);
		printf("There is %d combinations\n",count);
	}
}


 

 

 

您可能感兴趣的与本文相关的镜像

ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

<think>我们正在讨论排列组合的Java实现。排列Permutation)关注顺序,组合Combination)不关注顺序。排列:从n个不同元素中,任取m(m≤n)个元素按照一定的顺序排成一列。组合:从n个不同元素中,任取m(m≤n)个元素并成一组。根据引用[1][2][3]提供的思路,我们可以分别实现排列组合生成算法。组合生成Combination):我们可以使用回溯法(递归)来生成组合。例如,从数组[1,2,3,4]中选取2个元素的所有组合排列生成Permutation):排列也可以使用回溯法,但需要记录哪些元素已经被使用过,因为顺序不同视为不同的排列。下面分别给出组合排列的Java实现代码。1.组合生成Combination):我们采用递归回溯法,从起始位置开始,逐个选择元素,然后递归处理后续元素。2.排列生成Permutation):同样使用回溯法,但需要维护一个布尔数组来标记哪些元素已经被使用。注意:为了避免重复组合(如[1,2][2,1]被视为相同),在生成组合时,我们按顺序选取元素(即每次从当前位置的下一个位置开始选择)。下面给出具体的代码实现。</think>### Java排列组合算法实现 排列Permutation)关注元素顺序,组合Combination)忽略元素顺序。以下是两种算法的Java实现: #### 1. 组合生成算法(Combination) 使用回溯法实现: ```java import java.util.ArrayList; import java.util.List; public class CombinationGenerator { public static List<List<String>> generateCombinations(String[] elements, int r) { List<List<String>> result = new ArrayList<>(); backtrack(elements, r, 0, new ArrayList<>(), result); return result; } private static void backtrack(String[] elements, int r, int start, List<String> temp, List<List<String>> result) { if (temp.size() == r) { result.add(new ArrayList<>(temp)); return; } for (int i = start; i < elements.length; i++) { temp.add(elements[i]); backtrack(elements, r, i + 1, temp, result); // 关键:i+1避免重复 temp.remove(temp.size() - 1); } } public static void main(String[] args) { String[] data = {"a", "b", "c"}; List<List<String>> combs = generateCombinations(data, 2); System.out.println("组合结果(C(3,2)):" + combs); // 输出:[[a,b], [a,c], [b,c]] } } ``` #### 2. 排列生成算法(Permutation) 使用回溯+标记数组: ```java import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class PermutationGenerator { public static List<List<String>> generatePermutations(String[] elements) { List<List<String>> result = new ArrayList<>(); boolean[] used = new boolean[elements.length]; backtrack(elements, new ArrayList<>(), used, result); return result; } private static void backtrack(String[] elements, List<String> temp, boolean[] used, List<List<String>> result) { if (temp.size() == elements.length) { result.add(new ArrayList<>(temp)); return; } for (int i = 0; i < elements.length; i++) { if (!used[i]) { used[i] = true; temp.add(elements[i]); backtrack(elements, temp, used, result); temp.remove(temp.size() - 1); used[i] = false; // 回溯关键:重置状态 } } } public static void main(String[] args) { String[] data = {"a", "b", "c"}; List<List<String>> perms = generatePermutations(data); System.out.println("全排列结果(P(3)):" + perms); // 输出:[[a,b,c], [a,c,b], [b,a,c], [b,c,a], [c,a,b], [c,b,a]] } } ``` #### 关键区别: 1. **组合**:通过`start`参数控制选择起点,避免顺序重复 2. **排列**:使用`used`数组记录元素使用状态,允许顺序变化 3. **时间复杂度**: - 组合:$O(C(n,k))$ - 排列:$O(n!)$ #### 使用示例: ```java // 生成3选2组合 CombinationGenerator.generateCombinations(new String[]{"A","B","C"}, 2); // 生成3元素全排列 PermutationGenerator.generatePermutations(new String[]{"X","Y","Z"}); ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值