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

用Java实现排列、组合算法

阅读更多
1、我们知道,排列个数的计算公式如下:


组合个数的计算公式如下:


那么,计算排列或组合的数量,通过上面的公式就很容易就算出来了,其Java的实现如下:
	/**
	 * 计算阶乘数,即n! = n * (n-1) * ... * 2 * 1
	 * @param n
	 * @return
	 */
	private static long factorial(int n) {
		return (n > 1) ? n * factorial(n - 1) : 1;
	}

	/**
	 * 计算排列数,即A(n, m) = n!/(n-m)!
	 * @param n
	 * @param m
	 * @return
	 */
	public static long arrangement(int n, int m) {
		return (n >= m) ? factorial(n) / factorial(n - m) : 0;
	}

	/**
	 * 计算组合数,即C(n, m) = n!/((n-m)! * m!)
	 * @param n
	 * @param m
	 * @return
	 */
	public static long combination(int n, int m) {
		return (n >= m) ? factorial(n) / factorial(n - m) / factorial(m) : 0;
	}


2、有时候,我们不仅需要知道排列或组合的数量,而且需要知道有哪些排列或组合,并列举出所有的排列或组合,人工列举工作量大而且容易出错,那么,如何利用计算机帮忙列举出所有的这些排列或组合呢?
(1)排列
采用递归即可枚举出所有的排列情况,相关Java实现如下:
	/**
	 * 排列选择(从列表中选择n个排列)
	 * @param dataList 待选列表
	 * @param n 选择个数
	 */
	public static void arrangementSelect(String[] dataList, int n) {
		System.out.println(String.format("A(%d, %d) = %d", dataList.length, n, arrangement(dataList.length, n)));
		arrangementSelect(dataList, new String[n], 0);
	}

	/**
	 * 排列选择
	 * @param dataList 待选列表
	 * @param resultList 前面(resultIndex-1)个的排列结果
	 * @param resultIndex 选择索引,从0开始
	 */
	private static void arrangementSelect(String[] dataList, String[] resultList, int resultIndex) {
		int resultLen = resultList.length;
		if (resultIndex >= resultLen) { // 全部选择完时,输出排列结果
			System.out.println(Arrays.asList(resultList));
			return;
		}

		// 递归选择下一个
		for (int i = 0; i < dataList.length; i++) {
			// 判断待选项是否存在于排列结果中
			boolean exists = false;
			for (int j = 0; j < resultIndex; j++) {
				if (dataList[i].equals(resultList[j])) {
					exists = true;
					break;
				}
			}
			if (!exists) { // 排列结果不存在该项,才可选择
				resultList[resultIndex] = dataList[i];
				arrangementSelect(dataList, resultList, resultIndex + 1);
			}
		}
	}


(2)组合
采用递归即可枚举出所有的排列情况,相关Java实现如下:
	/**
	 * 组合选择(从列表中选择n个组合)
	 * @param dataList 待选列表
	 * @param n 选择个数
	 */
	public static void combinationSelect(String[] dataList, int n) {
		System.out.println(String.format("C(%d, %d) = %d", dataList.length, n, combination(dataList.length, n)));
		combinationSelect(dataList, 0, new String[n], 0);
	}

	/**
	 * 组合选择
	 * @param dataList 待选列表
	 * @param dataIndex 待选开始索引
	 * @param resultList 前面(resultIndex-1)个的组合结果
	 * @param resultIndex 选择索引,从0开始
	 */
	private static void combinationSelect(String[] dataList, int dataIndex, String[] resultList, int resultIndex) {
		int resultLen = resultList.length;
		int resultCount = resultIndex + 1;
		if (resultCount > resultLen) { // 全部选择完时,输出组合结果
			System.out.println(Arrays.asList(resultList));
			return;
		}

		// 递归选择下一个
		for (int i = dataIndex; i < dataList.length + resultCount - resultLen; i++) {
			resultList[resultIndex] = dataList[i];
			combinationSelect(dataList, i + 1, resultList, resultIndex + 1);
		}
	}


3、测试
(1)完整的测试代码如下
/**
 * 从n个数里取出m个数的排列或组合算法实现
 * @author chengesheng
 * @date 2016年9月28日 下午3:18:34
 */
import java.util.Arrays;
public class MathTest {

	public static void main(String[] args) {
		arrangementSelect(new String[] {
				"1", "2", "3", "4"
		}, 2);
		combinationSelect(new String[] {
				"1", "2", "3", "4", "5"
		}, 3);
	}

	/**
	 * 排列选择(从列表中选择n个排列)
	 * @param dataList 待选列表
	 * @param n 选择个数
	 */
	public static void arrangementSelect(String[] dataList, int n) {
		System.out.println(String.format("A(%d, %d) = %d", dataList.length, n, arrangement(dataList.length, n)));
		arrangementSelect(dataList, new String[n], 0);
	}

	/**
	 * 排列选择
	 * @param dataList 待选列表
	 * @param resultList 前面(resultIndex-1)个的排列结果
	 * @param resultIndex 选择索引,从0开始
	 */
	private static void arrangementSelect(String[] dataList, String[] resultList, int resultIndex) {
		int resultLen = resultList.length;
		if (resultIndex >= resultLen) { // 全部选择完时,输出排列结果
			System.out.println(Arrays.asList(resultList));
			return;
		}

		// 递归选择下一个
		for (int i = 0; i < dataList.length; i++) {
			// 判断待选项是否存在于排列结果中
			boolean exists = false;
			for (int j = 0; j < resultIndex; j++) {
				if (dataList[i].equals(resultList[j])) {
					exists = true;
					break;
				}
			}
			if (!exists) { // 排列结果不存在该项,才可选择
				resultList[resultIndex] = dataList[i];
				arrangementSelect(dataList, resultList, resultIndex + 1);
			}
		}
	}

	/**
	 * 组合选择(从列表中选择n个组合)
	 * @param dataList 待选列表
	 * @param n 选择个数
	 */
	public static void combinationSelect(String[] dataList, int n) {
		System.out.println(String.format("C(%d, %d) = %d", dataList.length, n, combination(dataList.length, n)));
		combinationSelect(dataList, 0, new String[n], 0);
	}

	/**
	 * 组合选择
	 * @param dataList 待选列表
	 * @param dataIndex 待选开始索引
	 * @param resultList 前面(resultIndex-1)个的组合结果
	 * @param resultIndex 选择索引,从0开始
	 */
	private static void combinationSelect(String[] dataList, int dataIndex, String[] resultList, int resultIndex) {
		int resultLen = resultList.length;
		int resultCount = resultIndex + 1;
		if (resultCount > resultLen) { // 全部选择完时,输出组合结果
			System.out.println(Arrays.asList(resultList));
			return;
		}

		// 递归选择下一个
		for (int i = dataIndex; i < dataList.length + resultCount - resultLen; i++) {
			resultList[resultIndex] = dataList[i];
			combinationSelect(dataList, i + 1, resultList, resultIndex + 1);
		}
	}

	/**
	 * 计算阶乘数,即n! = n * (n-1) * ... * 2 * 1
	 * @param n
	 * @return
	 */
	public static long factorial(int n) {
		return (n > 1) ? n * factorial(n - 1) : 1;
	}

	/**
	 * 计算排列数,即A(n, m) = n!/(n-m)!
	 * @param n
	 * @param m
	 * @return
	 */
	public static long arrangement(int n, int m) {
		return (n >= m) ? factorial(n) / factorial(n - m) : 0;
	}

	/**
	 * 计算组合数,即C(n, m) = n!/((n-m)! * m!)
	 * @param n
	 * @param m
	 * @return
	 */
	public static long combination(int n, int m) {
		return (n >= m) ? factorial(n) / factorial(n - m) / factorial(m) : 0;
	}
}


(2)测试结果
A(4, 2) = 12
[1, 2]
[1, 3]
[1, 4]
[2, 1]
[2, 3]
[2, 4]
[3, 1]
[3, 2]
[3, 4]
[4, 1]
[4, 2]
[4, 3]
C(5, 3) = 10
[1, 2, 3]
[1, 2, 4]
[1, 2, 5]
[1, 3, 4]
[1, 3, 5]
[1, 4, 5]
[2, 3, 4]
[2, 3, 5]
[2, 4, 5]
[3, 4, 5]

经验证,输出的结果正确,同预期结果相符。
  • 大小: 1.1 KB
  • 大小: 1.1 KB
分享到:
评论
1 楼 zpit7360 2016-11-16  

相关推荐

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

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

    排列组合算法实现

    排列组合算法实现,支持模板类。支持重复数的排列。算法采用递归方法,简单易懂。

    Java排列组合算法 - 郭睿的专栏 - CSDN博客

    Java排列组合算法 - 郭睿的专栏 - CSDN博客Java排列组合算法 - 郭睿的专栏 - CSDN博客

    java排列组合算法

    在Java中实现排列组合算法可以帮助我们解决很多实际问题,比如数据排序、数据筛选等。下面将详细介绍排列和组合的基本概念以及在Java中的实现方法。 **排列** 是指从n个不同元素中取出m(m≤n)个元素,按照一定的...

    Java排列组合算法

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

    6位数,共有几种排列组合的算法java实现

    6位数,共有几种排列组合的算法,java实现

    Java排列组合_组合算法

    本文将深入探讨如何在Java中实现排列组合,特别是基于描述中提到的"利用list及set的无序性"的方法。 首先,让我们理解排列和组合的基本概念。排列是指从n个不同元素中取出m(m≤n)个元素,按照一定的顺序排成一列...

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

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

    高效的java版排列组合算法

    Java排列组合算法是计算机科学中的一种基本算法,它广泛应用于数据分析、机器学习、人工智能等领域。下面将详细介绍高效的Java版排列组合算法的实现。 一、排列组合算法的概念 排列组合算法是指从n个元素中选择m个...

    从n个数组中取出所有排列组合(Java实现)

    总结来说,从n个数组中取出所有排列组合的Java实现涉及到递归算法、回溯法以及数据结构的操作。理解这些概念并能够熟练运用是成为一名优秀程序员的关键。通过这个例子,我们可以看到如何利用Java的灵活性和表达力来...

    [Java算法设计] - 排列组合.java

    此外,文档还提供了各种排列组合算法的详细代码示例和实现细节,包括递归和迭代方法。文档还涵盖了高级主题,如如何计算有重复元素的排列组合数量,以及如何优化这些算法的性能。 无论您是Java编程的初学者还是有...

    组合排列组合排列组合排列组合排列

    压缩包中的文件名为“Zuhe”,可能是实现组合排列算法的Java源代码文件。通过查看这个文件,我们可以了解具体的实现细节,包括使用的数据结构、递归或非递归的策略,以及如何处理边界条件等。 总的来说,组合排列是...

    关于各种排列组合java算法实现方法

    总结来说,Java中实现排列组合算法主要有两种策略:二进制状态法和递归。二进制状态法适合小规模数据,但效率较低;递归方法虽然直观,但可能导致性能问题。在实际应用中,应根据数据规模和性能需求选择合适的方法。...

    算法 排列组合生成器 后端

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

    排列组合的算法作业 java

    【排列组合的算法作业 Java】 在编程领域,排列和组合是经典的算法问题,它们属于组合数学的一部分,常常出现在数据结构与算法课程的作业中。排列指的是从给定的元素集合中选择并按特定顺序排列所有可能的组合,而...

    PermutationAndCombination(JAVA).rar_java permutation_java 算法_per

    在Java编程中,实现排列组合算法可以帮助我们处理多种实际问题,例如数据分析、数学建模和游戏逻辑等。本篇文章将深入探讨Java中实现排列组合算法的方法,并结合提供的资源进行详细解析。 首先,排列是有序的元素...

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

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

    Java和C语言实现各种经典算法

    Java和C语言都是广泛使用的编程语言,它们各有特点,但都能有效地实现各种算法。本资源包包含了用Java和C语言实现的各种经典算法,旨在帮助程序员深入理解算法原理,并提高编程实践能力。 Java是一种面向对象的、跨...

    组合数学中的生成排列算法java代码

    总之,这个Java程序结合了组合数学的排列概念和递归算法,通过深度优先搜索策略生成排列,并可能提供用户友好的界面展示。理解和掌握这些知识对于提升编程能力,特别是在算法设计和问题求解方面,有着显著的帮助。

    用java实现的经典递归算法

    本文主要探讨如何使用Java实现经典递归算法,旨在帮助初学者理解递归的工作原理及其应用。递归算法设计的关键在于将复杂问题分解为相似的子问题,直到子问题简单到可以直接解决。这通常涉及到两个要素:递归出口和...

Global site tag (gtag.js) - Google Analytics