對一組數據作無序排列(組合)的簡單實現

/**
	 * 對傳入的basecodes取sub位元素作組合.
	 * 
	 * @param basecodes:該集合的單元爲組合基數的單元元素
	 * @param sub:須要對基數作多少位的組合
	 * @return
	 */
	public static List<Set<String>> produceAllPrecode(List<String> basecodes, int sub) {
		List<Set<String>> result = new ArrayList<>();
		Set<String> single = new HashSet<>();
		int size = basecodes.size();
		if (size < sub) {
			return result;
		}
		// 總組數:C(size,sub)
		int total = cnm(size, sub);
		while (true) {
			if (result.size() >= total) {
				break;
			}
			single.add(basecodes.get(getRandom(size)));
			if (single.size() == sub) {
				if (!result.contains(single)) {
					Set<String> temp = new HashSet<>();
					temp.addAll(single);
					result.add(temp);
				}
				single.removeAll(single);
				continue;
			}
		}
		return result;
	}

	// 遞歸算法計算階乘:n!
	public static int factorials(int n) {
		return (n > 1) ? n * factorials(n - 1) : 1;
	}

	// 計算排列值:A(n,m),從給定n個數的元素中取出指定m個數的元素,進行排序
	public static int anm(int n, int m) {
		return factorials(n) / factorials(n - m);
	}

	// 計算組合值:C(n,m),從給定n個數的元素中僅僅取出指定m個數的元素,不考慮排序
	public static int cnm(int n, int m) {
		return anm(n, m) / factorials(m);
	}

	/**
	 * 生成0~max之間的隨機數。包含0,不包含max
	 */
	public static int getRandom(int max) {
		return new Random().nextInt(max);
	}

測試代碼java

// 組合測試
	@Test
	public void test04() {
		String[] codeArr = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
		// String[] codeArr = { "a", "b", "c", "d", "e"};
		List<String> basecodes = Arrays.asList(codeArr);
		int sub = 5;
		List<Set<String>> precodes = CqsscUtil.produceAllPrecode(basecodes, sub);
		List<String> sort = new ArrayList<>();
		for (Set<String> precode : precodes) {
			sort.add(precode.toString());
		}
		Collections.sort(sort);
		System.out.println("總組數:" + CqsscUtil.cnm(basecodes.size(), sub));
		for (String code : sort) {
			System.out.println(code);
		}
	}
相關文章
相關標籤/搜索