`
yangtao309
  • 浏览: 66792 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

排列组合算法实现【学习】

阅读更多
一个从M个数字里面取N个数字的组合
没用到递归的实现,将选取的位置标记为1没选取的标记为0
返回的是数组的形式。

版本1
public class CombineUtil {
	
	private static int[] copy(int[] bs){
		int[] result = new int[bs.length];
		for(int i=0;i<bs.length;i++){
			result[i] = bs[i];
		}
		return result ;
	}


	public static void print(List<int[]> l){
		for(int i=0;i<l.size();i++){
			int[] a = (int[])l.get(i);
			for(int j=0;j<a.length;j++){
				System.out.print(a[j]+"\t");
			}
			System.out.println();
		}
	}

	public static void print(int[] a){
		for(int j=0;j<a.length;j++){
			System.out.print(a[j]+"\t");
		}
		System.out.println();
	}
	
	/**
	 * 从m里选n个数字
	 * @param m
	 * @param n
	 * @return
	 */
	public static List<int[]> combineEx(int m, int n) {
		if (m < n) {
			return null;
		}
		
		List<int[]> list = new ArrayList<int[]>();
		int[] cn = new int[m];
		for (int i = 0; i < cn.length; i++) {
			if (i < n) {
				cn[i] = 1;
			} else {
				cn[i] = 0;
			}
		}
		
		boolean flag = true;
		
		do {
			int pos = 0;
			int sum = 0;
			boolean tempFlag = true;
			
			list.add(copy(cn));
			if (m == n || m == 0) {
				return list;
			}
			
			for (int i = 0; i < m - 1; i++) {
				if (cn[i]==1 && cn[i+1]==0) {
					cn[i]=0;
					cn[i+1]=1;
					pos = i;
					break;
				}
			}
			
			for (int i = 0; i < pos; i++) {
				if (cn[i] == 1) {
					sum ++;
				}
			}
			
			for (int i = 0; i < pos; i++) {
				if (i < sum) {
					cn[i] = 1;
				} else {
					cn[i] = 0;
				}
			}
			
			for (int i = m-n; i < cn.length; i++) {
				if (cn[i] == 0) {
					tempFlag = false;
					break;
				}
			}
			
			flag = !tempFlag;
		} while (flag);
		list.add(copy(cn));
		
		return list;
	}
	
	public static void main(String[] args) {

		try {
			CombineUtil.print(combineEx(3, 3));

		} catch (Exception e) {
			e.printStackTrace();
		}  
		
	}




版本二

public class CombinationEx {
	
	private List<String> list = new ArrayList<String>();
	
	private void mn(int m, int n) {
		if ( m < n) {
			throw new IllegalArgumentException("参数异常"); 
		}
		
		BitSet bs = new BitSet(m);
		for (int i = 0; i < n; i++) {
			bs.set(i, true);
		}
		
		do {
			printAll(m, bs);
		} while(moveNext(bs, m)); 
	}
	
	private void printAll(int m, BitSet bs) {
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < m; i++) {
			if (bs.get(i)) {
				sb.append("1").append(",");
			} else {
				sb.append("0").append(",");
			}
		}
		sb.setLength(sb.length() - 1);
		list.add(sb.toString());
	}
	
	private boolean moveNext(BitSet bs, int m) {
		int start = -1;
		while (start < m) {
			if (bs.get(++start)) {
				break;
			}
		}
		
		if (start >= m) {
			return false;
		}
		
		int end = start;
		while (end < m) {
			if (!bs.get(++end)) {
				break;
			}
		}
		
		if (end >= m) {
			return false;
		}
		
		for (int i = 0; i < end; i++) {
			bs.set(i, false);
		}
		
		for (int i = 0; i < end - start - 1; i++) {
			bs.set(i);
		}
		
		bs.set(end);
		return true;
	}
	
	private List<String> getList() {
		return list;
	}
	
	public static void main(String[] args) {
		CombinationEx co = new CombinationEx();
		co.mn(5, 3);
		for (int i = 0; i < co.getList().size(); i++) {
			System.out.println(co.getList().get(i));
		}
	}
}


下面介绍全排列的算法

public class Arrange {
	private int total = 0;
	private ArrayList<String> arrangeList = new ArrayList<String>();

	public Arrange() {
	}

	private void swap(String list[], int k, int i) {
		String c3 = list[k];
		list[k] = list[i];
		list[i] = c3;
	}

	public void perm(String list[], int k, int m) {
		if (k > m) {
			StringBuffer sb = new StringBuffer();
			for (int i = 0; i <= m; i++) {
				sb.append(list[i]).append(",");
			}
			if (sb.length() > 0) {
				sb.setLength(sb.length() - 1);
			}
			arrangeList.add(sb.toString());
			total++;
		} else {
			for (int i = k; i <= m; i++) {
				swap(list, k, i);
				perm(list, k + 1, m);
				swap(list, k, i);
			}
		}
	}

	public int getTotal() {
		return total;
	}

	public ArrayList<String> getArrangeList() {
		return arrangeList;
	}

	public static void main(String args[]) {
		// String list[] = { "1", "2", "3", "4", "5" };
		String list[] = { "1", "2", "3" };
		Arrange ts = new Arrange();
		ts.perm(list, 0, list.length - 1);
		for (int i = 0; i < ts.getArrangeList().size(); i++) {
			System.out.println(ts.getArrangeList().get(i));
		}
		System.out.println("total:" + ts.total);
	}
}

分享到:
评论
2 楼 night_stalker 2010-08-16  
lz 注定要杯具的,下面跑跑题:


A

话说,Ruby 1.9.2 的数组有各种排列组合方法,使用超简单的 ……
irb(main):001:0> [1,2,3,4].combination(3).to_a # 组合
=> [[1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]]
irb(main):002:0> [1,2,3].permutation(3).to_a # 排列
=> [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]

如果直接给个闭包作参数,就可以不生成中间结果,以单个排列/组合结果为元素跑循环。


B

看 Array#combination 的实现(C),用了一个栈:
static VALUE
rb_ary_combination(VALUE ary, VALUE num)
{
    long n, i, len;

    n = NUM2LONG(num);
    RETURN_ENUMERATOR(ary, 1, &num);
    len = RARRAY_LEN(ary);
    if (n < 0 || len < n) {
	/* yield nothing */
    }
    else if (n == 0) {
	rb_yield(rb_ary_new2(0));
    }
    else if (n == 1) {
	for (i = 0; i < len; i++) {
	    rb_yield(rb_ary_new3(1, RARRAY_PTR(ary)[i]));
	}
    }
    else {
	volatile VALUE t0 = tmpbuf(n+1, sizeof(long));
	long *stack = (long*)RSTRING_PTR(t0);
	volatile VALUE cc = tmpary(n);
	VALUE *chosen = RARRAY_PTR(cc);
	long lev = 0;

	MEMZERO(stack, long, n);
	stack[0] = -1;
	for (;;) {
	    chosen[lev] = RARRAY_PTR(ary)[stack[lev+1]];
	    for (lev++; lev < n; lev++) {
		chosen[lev] = RARRAY_PTR(ary)[stack[lev+1] = stack[lev]+1];
	    }
	    rb_yield(rb_ary_new4(n, chosen));
	    if (RBASIC(t0)->klass) {
		rb_raise(rb_eRuntimeError, "combination reentered");
	    }
	    do {
		if (lev == 0) goto done;
		stack[lev--]++;
	    } while (stack[lev+1]+n == len+lev+1);
	}
    done:
	tmpbuf_discard(t0);
	tmpary_discard(cc);
    }
    return ary;
}

上面代码前面一大段是各种边界检查什么的,下面那几行 for(;;) 便是核心逻辑。
返回数组 chosen = 栈(index) map 到数组元素,每轮更新一下栈。实现也超简单 ……
1 楼 yangtao309 2010-08-16  
请看懂算法了的 给个留言好伐
不要看到标题 就投新手贴
只是希望多交流而已

相关推荐

    PHP实现多种类型的排列组合算法

    下面将详细讨论PHP如何实现排列组合算法。 首先,排列和组合是离散数学中的基本概念。排列是指从n个不同元素中取出m(m≤n)个元素,按照一定的顺序排列起来,形成不同的排列方式。组合则是指从n个不同元素中不考虑...

    Java排列组合算法分析和代码实现

    总之,这个资源包提供了一个很好的平台,让你能够深入理解并实践Java中的排列组合算法。通过学习和理解这些代码,你不仅可以增强算法设计能力,还能提高解决实际编程问题的能力。记得动手实践,结合文档和代码,将...

    基于c语言的排列组合算法

    学习这个C语言实现的排列组合算法,可以帮助你理解递归思想,提高处理组合数学问题的能力,并且在实际编程中能更有效地解决问题。在实践中,你可以通过调整参数,测试不同的元素集合并观察结果,以加深对算法的理解...

    组合数学之排列组合生成算法

    组合数学之排列组合生成算法,很好的学习组合排列算法的资料

    Python实现的简单排列组合算法示例

    在计算机科学中,排列组合算法是算法设计与分析中的一个重要部分,广泛应用于各种问题求解场景,比如:算法竞赛、数据结构设计、数据库查询优化等。Python语言以其简洁易读的语法和强大的标准库支持,在实现排列组合...

    排列组合算法

    实际应用中,排列组合算法广泛应用于各种场景,如密码生成、数据分析、游戏逻辑、机器学习模型的参数搜索等。例如,在设计一个密码生成器时,可以利用组合算法生成所有可能的字符组合,以确保密码的多样性。 总的来...

    排列组合生成算法

    2. **组合算法实现**: - **组合计数**:组合的数量可以通过组合公式C(n, k) = n! / (k!(n-k)!)计算,其中“!”表示阶乘。 - **深度优先搜索**:同样可以使用递归的深度优先搜索策略来生成组合,每次选择一个元素...

    实现了排列组合算法的类(JAVA).rar

    这个"实现了排列组合算法的类(JAVA).rar"文件提供了一种高效的JAVA实现,可以处理任意类型数组的排列和组合。下面将详细讨论排列组合的基本概念,以及在JAVA中实现这些算法的关键点。 排列是指从n个不同元素中...

    Java排列组合算法

    本文将深入探讨Java中实现排列组合算法的方法,帮助开发者更好地理解和运用这些概念。 排列是有序的选择,而组合是无序的选择。在Java中,我们可以使用递归、回溯法或者迭代的方式来实现这两种算法。下面我们将详细...

    算法 排列组合生成器 后端

    这个项目为开发者提供了一个学习和实践排列组合算法、SpringBoot框架以及H2数据库整合的绝佳案例。它不仅展示了如何在后端实现复杂的算法,还涵盖了数据库管理和API设计等多个核心技能。对于希望提升后端开发能力的...

    排列组合的全排列算法(交换算法)

    以下是交换算法实现全排列的基本步骤: 1. 初始化:设定一个起始索引,通常是0,和一个结束索引,为数组长度减1。 2. 内部循环:对于每个起始索引,使用另一层循环从起始索引到结束索引,进行以下操作: - 比较...

    Java排列组合_组合算法

    在编程领域,排列组合是算法设计中的一个重要概念,特别是在数据结构和算法的学习中。Java作为一种广泛应用的编程语言,提供了丰富的工具来实现这类算法。本文将深入探讨如何在Java中实现排列组合,特别是基于描述中...

    阶乘与排列组合算法 各行各业都能用到

    阶乘与排列组合算法是计算机科学中基础但至关重要的概念,尤其在概率论、统计学、图论和算法设计等领域有着广泛的应用。阶乘(n!)是计算一个正整数n的所有小于等于n的正整数乘积,而排列组合则是解决如何从给定元素...

    C经典算法之排列组合

    ### C经典算法之排列组合 #### 知识点解析 **排列组合**是计算机科学与数学中的一个重要概念,广泛应用于密码学、数据处理、优化问题等...理解排列组合的基本原理及其实现方法对于学习高级算法和数据结构非常重要。

    JS实现的排列组合算法示例

    JS实现的排列组合算法中,组合算法的计算可通过递归或循环来实现。例如,在上述文件中提供了一个关于组合的实例代码。该代码通过嵌套循环的方式,从一个数字数组中选取若干个元素的所有可能组合。每层循环代表选择的...

    高效的java版排列组合算法

    二、高效的Java版排列组合算法实现 下面是高效的Java版排列组合算法的实现代码: ```java public class Copy_2_of_StatisAnyThree { public static void main(String[] args) { Copy_2_of_StatisAnyThree s = new...

    排列组合-插入算法

    在编程领域,排列组合是一种常见的算法问题,尤其在数据结构和算法的学习中占有重要地位。排列是指从n个不同元素中取出m(m≤n)个元素,按照一定的顺序排成一列的所有可能的方式;组合则是指从n个不同元素中不考虑...

    PHP实现的简单排列组合算法应用示例

    本文将详细探讨如何使用PHP实现简单的排列组合算法,并通过一个具体的实例来展示其应用。 首先,我们需要理解排列和组合的基本概念。排列是指从n个不同元素中取出m(m≤n)个元素,按照一定的顺序排成一列,而组合...

    基于hadoop用并行递归实现排列组合运算

    本篇文章将介绍如何使用Hadoop框架来实现一个并行递归算法,用于生成给定长度的所有可能的排列组合。 问题的具体描述如下:给定一个整数`M`,程序需要输出由数字`1`、`2`、`3`、`4`组成的长度为`M`的所有排列组合。...

Global site tag (gtag.js) - Google Analytics