排列组合算法的实现代码

有些时候我们需要利用程序实现排列组合算法, 下面是我根据网上的代码改写的awk代码, 可实现排列或是组合, 当然元素数目不能太大.

排列

# Language: bash
awk ' BEGIN {
	Ndat=3
	for(i=1; i<=Ndat; i++) {P[i]=i}
	YesDone=0
	while(!YesDone) {
		for(i=1; i<=Ndat; i++) printf"%d ", P[i]
		print ""
		NextPermut(Ndat, P)
	}
}

function NextPermut(Ndat, P) {
	if (Ndat==0) {YesDone=1; return}
	# 从后向前查找,看有没有后面的数大于前面的数的情况P(i-1)<Pi,若有则停在后一个数的位置。
	# 若没有后面的数大于前面的数的情况,说明已经到了最后一个排列,返回
	for(i=Ndat; i>0 && P[i-1]>P[i]; i--) { }
	Iend=i
	if(Iend==1) { YesDone=1; return }

	# 从后查到Iend,查找大于P(Iend-1)的最小的数,记入Ibeg
	Ibeg=Iend
	for (i=Ndat; i>=Iend; i--) { if (P[Iend-1]< P[i] && P[i]< P[Ibeg]) Ibeg=i }

	#交换p[Ibeg]和p[Iend-1]
	tmp=P[Ibeg]; P[Ibeg]=P[Iend-1]; P[Iend-1]=tmp

	#倒置p[Iend]到p[Ndat]
	j=Ndat
	for(i=Iend; i< j; i++) {
		tmp=P[j]; P[j]=P[i]; P[i]=tmp
		j--
	}
}
'

组合

# Language: bash
awk ' BEGIN {
	m=6; n=4;
	a[1]="A"; a[2]="B"; a[3]="C"; a[4]="D"; a[5]="E"; a[6]="F"

	Comb(m,n)
	#RecComb(m, n, 1, n)
}

function RecComb(m, n, start, count, i,j) { # 递归实现
	for(i=start; i<=m+1-count; i++) {
		b[count]=i
		if(count>1) RecComb(m, n, i+1, count-1);
		else { for(j=n; j>0; j--) printf("%s ",a[b[j]]); print "" }
	}
}

function Comb(m, n) { # 非递归
	idx=1
	p[idx]=1					#取第一个元素
	while(1) {
		if(p[idx]>m) {			#取到底了,回退
			if(idx==1) break	#各种情况取完了,不能再回退了
			idx--				#回退到前一个
			p[idx]++			#替换元素
		} else if(idx==n) {		#取够了,输出
			for(i=1; i<=m; i++) printf("%s ", a[p[i]])
			print ""
			p[idx]++			#替换元素
		} else {				#多取一个元素
			idx++
			p[idx]=p[idx-1]+1
		}
	}
}
'

如果是在Python中, 就容易多了, 可参考下面的代码.

# Language: python
import copy
import random
import itertools

n=6
seqIni=list(itertools.combinations('ABCDEFGHIJ', n))
Nseq=len(seqIni)
print Nseq

fh = open("Comb", "w")

for i in seqIni :
	k=' '.join([str(j) for j in i])
	fh.write(k+"\n")

fh.close()

for Nrnd in range (1):
	seq=copy.deepcopy(seqIni)
	if Nrnd==1:
		tmp=seq[1]
		seq[1]=seq[Nseq-1]
		seq[Nseq-1]=tmp
	if(Nrnd>1): random.shuffle(seq)
	

#	s="%d"%(Nrnd)
#	fh = open("Comb"+s, "w")

#	for i in seq :
#		k=' '.join([str(j) for j in i])
#		fh.write(k+"\n")
#	fh.close()

Ntot=0
for i in range (Nseq):
	if seq[i]!="":
		Ntot += 1
#			if(Ntot>17):
#			print Ntot, seq[i]
#			fh.write("%d "%(Ntot))
#			for kk in seq[i] :
#				k='  '.join([str(jk) for jk in kk])
#				fh.write(k+" ")
#			fh.write("
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是Java中实现排列组合代码示例: ``` import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class PermutationCombination { // 计算阶乘 public static int factorial(int n) { int result = 1; for (int i = 1; i <= n; i++) { result *= i; } return result; } // 计算排列数 public static int permutation(int n, int r) { return factorial(n) / factorial(n - r); } // 计算组合数 public static int combination(int n, int r) { return permutation(n, r) / factorial(r); } // 递归实现全排列 public static void permutation(List<Integer> nums, int start, List<List<Integer>> result) { if (start == nums.size()) { result.add(new ArrayList<>(nums)); return; } for (int i = start; i < nums.size(); i++) { swap(nums, start, i); permutation(nums, start + 1, result); swap(nums, start, i); } } // 交换数组中两个元素的位置 public static void swap(List<Integer> nums, int i, int j) { int temp = nums.get(i); nums.set(i, nums.get(j)); nums.set(j, temp); } public static void main(String[] args) { List<Integer> nums = Arrays.asList(1, 2, 3); // 计算排列数和组合数 System.out.println("permutation: " + permutation(5, 3)); System.out.println("combination: " + combination(5, 3)); // 计算全排列 List<List<Integer>> result = new ArrayList<>(); permutation(nums, 0, result); System.out.println("permutation result: " + result); } } ``` 输出结果为: ``` permutation: 60 combination: 10 permutation result: [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 2, 1], [3, 1, 2]] ``` 其中,`permutation`和`combination`函数分别计算排列数和组合数,`permutation`函数使用阶乘实现,`combination`函数使用排列数实现。 `permutation`函数使用递归实现全排列,`swap`函数用于交换数组中两个元素的位置。在`main`函数中,我们使用`permutation`函数计算`[1, 2, 3]`的全排列,并将结果存储在`result`变量中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值