组合Combination 分布数组计算

组合分布数组计算:

从m个样本中抽取n个,进行组合分布。

例如:从[0,1,2,3]中抽取2个的组合分布为:[0,1], [0,2], [1,2], [0,3], [1,3], [2,3]六种情况。

/*
@function: CombinationArray
@brief:m个数中取n个数的组合分布
@param [i]   m 样本总数 [0, 1 , ... , m-1]
@param [i]   n 抽样个数
@param [o] res 组合分布数组
@return: <=0代表运行错误;>0代表:组合分布数组的组数
@warn:函数返回的是组合的组数,不是内存所需大小。
*  内存所需大小=组合数*n
*/
int CombinationArray(int m, int n, int* res) {
	if (m < n || n < 0 || m < 0)
		return -1;

	// 生成n个位置(值,最小,最大)
	int* seat = new int[n*3];

	// 初始化位置
	for (int i = 0; i < n; ++i) {
		seat[i] = i;                 // 该位置的号码
		seat[i + n] = i;             // 该位置的最小号码
		seat[i + n + n] = i + m - n; // 该位置的最大号码
	}

	// 计算组合分布
	int cnt = 0;
	while (cnt > -1) {
		// 数据输出与统计
		if (res) {
			memcpy(res, seat, sizeof(int)*n);
			res += n;
		}
		++cnt;

		// 最小位置变化
		seat[0]++;

		// 变化产生的进位检查
		for (int i = 0; i < n; ++i) {
			if (seat[i] > seat[i + 2 * n] || (seat[i] == seat[i + 1] && (i + 1 < n))) {
				// 进位
				if (i == n - 1) {
					cnt = -cnt;
					break;
				}
				seat[i] = seat[i + n];
				seat[i + 1]++;
			}
		}
	}

	// 返回组合数
	return -cnt;
}

代码测试:

int main()
{
	int m = 4;
	int n = 2;

	// 计算组合数
	int num = CombinationArray(m, n, NULL);
	if (num < 0)
	{
		std::cout << "参数出错" << std::endl;
		return 0;
	}

	// 开辟组合分布的内存空间:组合数*每组的样本数(抽样数)
	int* buf = new int[num*n];

	// 计算组合分布
	num = CombinationArray(m, n, buf);

	// 输出组合分布
	std::cout << "num:" << num << std::endl;;
	for (int i = 0; i < num; ++i) {
		std::cout << "[";
		for (int j = 0; j < n; ++j) {
			std::cout << buf[i*n + j] << " ";
		}
		std::cout << "]" << std::endl;
	}
	std::cout << std::endl;
	
	return 0;
}

测试结果:

num:6
[0 1 ]
[0 2 ]
[1 2 ]
[0 3 ]
[1 3 ]
[2 3 ]

Python语言使用itertools库计算排列组合分布:

# -*- coding: utf-8 -*-

#从itertools导入
from itertools import permutations, combinations

#排列:[0,1,2]中取2的所有排列情况
list(permutations([0,1,2],2))

#组合:[0,1,2,3]中取2的所有组合情况
list(combinations([0,1,2,3],2))

运行结果:

C:\Users\mylaf>python
Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 22:22:05) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> #从itertools导入
... from itertools import permutations, combinations
>>>
>>> #排列:[0,1,2]中取2的所有排列情况
... list(permutations([0,1,2],2))
[(0, 1), (0, 2), (1, 0), (1, 2), (2, 0), (2, 1)]
>>>
>>> #组合:[0,1,2,3]中取2的所有组合情况
... list(combinations([0,1,2,3],2))
[(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3)]
>>>

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值