All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.hutool.core.math.Combination Maven / Gradle / Ivy

There is a newer version: 5.8.33
Show newest version
package cn.hutool.core.math;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;

/**
 * 组合,即C(n, m)
* 排列组合相关类 参考:http://cgs1999.iteye.com/blog/2327664 * * @author looly * @since 4.0.6 */ public class Combination implements Serializable { private static final long serialVersionUID = 1L; private final String[] datas; /** * 组合,即C(n, m)
* 排列组合相关类 参考:http://cgs1999.iteye.com/blog/2327664 * * @param datas 用于组合的数据 */ public Combination(String[] datas) { this.datas = datas; } /** * 计算组合数,即C(n, m) = n!/((n-m)! * m!) * * @param n 总数 * @param m 选择的个数 * @return 组合数 */ public static long count(int n, int m) { if (0 == m || n == m) { return 1; } return (n > m) ? NumberUtil.factorial(n, n - m) / NumberUtil.factorial(m) : 0; } /** * 计算组合总数,即C(n, 1) + C(n, 2) + C(n, 3)... * * @param n 总数 * @return 组合数 */ public static long countAll(int n) { if (n < 0 || n > 63) { throw new IllegalArgumentException(StrUtil.format("countAll must have n >= 0 and n <= 63, but got n={}", n)); } return n == 63 ? Long.MAX_VALUE : (1L << n) - 1; } /** * 组合选择(从列表中选择m个组合) * * @param m 选择个数 * @return 组合结果 */ public List select(int m) { final List result = new ArrayList<>((int) count(this.datas.length, m)); select(0, new String[m], 0, result); return result; } /** * 全组合 * * @return 全排列结果 */ public List selectAll() { final List result = new ArrayList<>((int) countAll(this.datas.length)); for (int i = 1; i <= this.datas.length; i++) { result.addAll(select(i)); } return result; } /** * 组合选择 * * @param dataIndex 待选开始索引 * @param resultList 前面(resultIndex-1)个的组合结果 * @param resultIndex 选择索引,从0开始 * @param result 结果集 */ private void select(int dataIndex, String[] resultList, int resultIndex, List result) { int resultLen = resultList.length; int resultCount = resultIndex + 1; if (resultCount > resultLen) { // 全部选择完时,输出组合结果 result.add(Arrays.copyOf(resultList, resultList.length)); return; } // 递归选择下一个 for (int i = dataIndex; i < datas.length + resultCount - resultLen; i++) { resultList[resultIndex] = datas[i]; select(i + 1, resultList, resultIndex + 1, result); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy