社区
数据结构与算法
帖子详情
请问高手们:怎么才可以直接输出组合啊??
mis98ZB
2002-01-31 02:36:43
有两种情况:
1。不放回抽样,从N个数中任选M个的所有组合。(M<=N)
2。放回抽样,每次从N个数中选一个,选M次的所有组合。(M=N好象是一个突变点)
唉,数学学的太菜了,老大们,帮忙补补课啊!
...全文
135
5
打赏
收藏
请问高手们:怎么才可以直接输出组合啊??
有两种情况: 1。不放回抽样,从N个数中任选M个的所有组合。(M<=N) 2。放回抽样,每次从N个数中选一个,选M次的所有组合。(M=N好象是一个突变点) 唉,数学学的太菜了,老大们,帮忙补补课啊!
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
5 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
mis98ZB
2002-02-01
打赏
举报
回复
万分感谢版主starfish(海星)的代码!!!
先仔细研究一下,有不懂的地方还望指教。
也感谢intfree()和shshsh_0510()的指点。
资料一下子多了起来,先看看,
想清楚了再提问。
starfish
2002-02-01
打赏
举报
回复
现在是不是流行用计算机算体育彩票呀~~
怎么这么多人问这个问题,sigh~~
下面的代码是我写的用来计算组合数的一个类:
#ifndef _COMBINATION_H_
#define _COMBINATION_H_
/*
combination.h
这个头文件定义了一个Combinatin类
利用该类可以生成从m个数中取出n个数的组合数
并且过滤出满足一定条件的组合数
注意,这里的m, n 都必须是0~255之间的整数
*/
#include <iostream>
#include <iomanip>
#include <vector>
#include <list>
using namespace std;
typedef unsigned char byte;
typedef vector<byte> ByteArray;
class Combination : public list<ByteArray>
{
protected:
byte m, n; // 生成从m个数中取出n个数的组合
vector<bool> enabled; // 用来标记1~m中哪些数字可以使用
ByteArray LowBound, HighBound; // 记录组合数中每一位的可取值范围
bool repeatable; // 标记生成的组合数中的数字是否可以重复出现
protected:
// 回溯搜索组合数的第i位
void SearchComb(int i, ByteArray& L);
public:
/*
功能: 类Combination的构造器
参数: m 组合数中每一位可取得最大整数
n 组合数的位数
说明:
例如,如果要生成从整数1~30中取出7个整数的组合数,
应该声明如下:
Combination combs(30, 7);
*/
Combination(byte m, byte n);
/*
功能:设置组合数中第i位的取值范围
参数:i 设置组合数中第i位数的取值范围,1 <= i <= n
lbound 取值下界, 1 <= lbound <= m
hbound 取值上界, 1 <= hbound <= m
说明:
例如,如果要设置组合数的1位取值范围为3~5
则应该调用:
SetBound(1, 3, 5);
如果要固定组合数的第一位为4,则应该调用
SetBound(1, 4, 4);
注意:
1. 这里的i从1开始计数
2. 如果参数i, lbound, hbound超出了允许的范围,
则调用该方法不会有任何结果
3. 组合数中每一位的默认取值范围是1~m,如果原来设置了
第i位的取值范围,现在想取消原来的设置,则应该调用:
SetBound(i, 1, m);
*/
void SetBound(byte i, byte lbound, byte hbound);
// 清除原来设置的所有的取值范围
void ResetAllBound();
// 在组合数中禁用数字x
void Disable(byte x);
// 在组合数中禁用从a到b所有的数字
void Disable(byte a, byte b);
// 在组合数中重新允许使用数字x
void Enable(byte x);
// 在组合数中重新允许使用从a到b所有的数字
void Enable(byte a, byte b);
// 生成组合数
void GenerateCombination();
// 设置组合中的数字是否可以重复
void SetRepeatable(bool repeatable);
// 这是一个虚函数
// 可以在派生类中加入你自己的过滤器
virtual void Filter() { }
};
// 回溯搜索组合数的第i位
// 注意,搜索出的组合数是从小到大排列的
void Combination::SearchComb(int i, ByteArray& L) {
if (i == n) {
this->push_back(L);
} else {
int begin;
if (i == 0) {
begin = LowBound[i];
} else {
begin = LowBound[i];
if ( (repeatable == false) && (LowBound[i] < L[i-1] + 1) ) {
begin = L[i-1] + 1;
}
}
for (int j = begin; j <= HighBound[i]; j++) {
if (enabled[j]) {
if (repeatable == false) enabled[j] = false;
L[i] = j;
SearchComb(i+1, L);
if (repeatable == false) enabled[j] = true;
}
}
}
}
/*
功能: 类Combination的构造器
参数: m 组合数中每一位可取得最大整数
n 组合数的位数
说明:
例如,如果要生成从整数1~30中取出7个整数的组合数,
应该声明如下:
Combination combs(30, 7);
*/
Combination::Combination(byte m, byte n) {
this->m = m;
this->n = n;
this->repeatable = false;
LowBound.resize(n);
HighBound.resize(n);
ResetAllBound();
enabled.resize(m + 1);
Enable(1, m);
}
/*
功能:设置组合数中第i位的取值范围
参数:i 设置组合数中第i位数的取值范围,1 <= i <= n
lbound 取值下界, 1 <= lbound <= m
hbound 取值上界, 1 <= hbound <= m
说明:
例如,如果要设置组合数的1位取值范围为3~5
则应该调用:
SetBound(1, 3, 5);
如果要固定组合数的第一位为4,则应该调用
SetBound(1, 4, 4);
注意:
1. 这里的i从1开始计数
2. 如果参数i, lbound, hbound超出了允许的范围,
则调用该方法不会有任何结果
3. 组合数中每一位的默认取值范围是1~m,如果原来设置了
第i位的取值范围,现在想取消原来的设置,则应该调用:
SetBound(i, 1, m);
*/
void Combination::SetBound(byte i, byte lbound, byte hbound) {
if( lbound >= 1 && hbound <= m && i >= 1 && i <= n) {
i--;
LowBound[i] = lbound;
HighBound[i] = hbound;
}
}
// 清除原来设置的所有的取值范围
void Combination::ResetAllBound() {
for (int i = 0; i < n; i++) {
LowBound[i] = 1;
HighBound[i] = m;
}
}
void Combination::Disable(byte x) {
if (x >=1 && x <= m) {
enabled[x] = false;
}
}
void Combination::Disable(byte a, byte b) {
for (byte i = a; i <= b; i++) {
Disable(i);
}
}
void Combination::Enable(byte x) {
if (x >=1 && x <= m) {
enabled[x] = true;
}
}
void Combination::Enable(byte a, byte b) {
for (byte i = a; i <= b; i++) {
Enable(i);
}
}
// 设置组合中的数字是否可以重复
void Combination::SetRepeatable(bool repeatable) {
this->repeatable = repeatable;
}
// 生成组合数
void Combination::GenerateCombination() {
ByteArray L(n); // 用来存储每一组的组合数
this->clear();
SearchComb(0, L); // 搜索组合数
Filter(); // 调用过滤器进行过滤
}
// 重载输出运算符
ostream operator<<(ostream& out, const ByteArray& array) {
for (int i = 0; i < array.size(); i++) {
out<< setw(4) << int( array[i] );
}
return out;
}
ostream operator<<(ostream& out, const Combination& combs) {
list<ByteArray>::const_iterator iter;
for (iter = combs.begin(); iter != combs.end(); iter++) {
out << *iter << endl;
}
out << "Total count is : " << combs.size() << endl;
return out;
}
#endif
下面是一个测试用的例子 test.cpp:
#include "combination.h"
#include <vector>
#include <algorithm>
using namespace std;
class MyCombs : public Combination
{
private:
// 这个过滤器将求出组合数中两两相减的值
// 如果所有不重复的差值总数等于一个常数X则保留该组合
// 否则删除该组合
void Filter_A() {
const int X = 18;
list<ByteArray>::iterator iter;
for( iter = this->begin(); iter != this->end(); )
{
ByteArray& array = *iter;
vector<int> temp; // 注意,temp一定要在这个for循环里面声明
// 下面这个二重for循环用来求两辆相减的绝对值,并且把不重复的元素放在temp中
for(int i = 0; i < array.size(); i++ ) {
for( int j = i+1; j < array.size(); j++ ) {
int d = abs(int(array[i]) - int(array[j]));
// 如果在temp中找不到该差值
if( find( temp.begin(), temp.end(), d) == temp.end() ) {
temp.push_back(d);
}
}
}
// 直接判断temp中的元素的数目就可以了,因为原来temp中的值都是互不相同的
if( temp.size() != 18 ) {
list<ByteArray>::iterator old_iter = iter;
iter++;
this->erase(old_iter);
} else {
iter++;
}
}
}
void Filter_B() {
// 可以在这里加入你自己的过滤器
}
public:
MyCombs(byte m, byte n) :
Combination(m, n)
{
}
// 覆盖父类的虚方法,
// 在这个函数中填入你自己的过滤器即可
// 如果有多个过滤器,将其写成函数,
// 在这个函数中一一调用即可
void Filter() {
//Filter_A();
// 你也可以加上Filter_B(); Filter_C()...., etc
}
};
int main()
{
MyCombs combs(4, 3);
combs.SetBound(1, 1, 4);
combs.SetBound(2, 1, 4);
combs.SetBound(3, 1, 4);
combs.SetRepeatable(true);
combs.GenerateCombination();
cout << "result is : " << endl;
cout << combs << endl;
return 0;
}
intfree
2002-01-31
打赏
举报
回复
我记得starfish的主页上就有,
而且这个问题在csdn上出现过多次了,
你可以搜索前面的帖子。
good luck!
shshsh_0510
2002-01-31
打赏
举报
回复
卢开澄的《组合数学》中有好几种生成算法:
mis98ZB
2002-01-31
打赏
举报
回复
除了生成排列、并检测重复以外,有什么别的妙门吗?
组合
的
输出
排列与
组合
是常用的数学方法,其中
组合
就是从n个元素中抽出r个元素(不分顺序且r≤n),我们可以简单地将n个元素理解为自然数12n,从中任取r个数。现要求你
输出
所有
组合
。例如n5r3123124125134135145234235245345。
组合
导航原理-松
组合
+紧
组合
概念
文章目录
组合
导航系统
组合
导航的概念广义狭义什么是滤波器互补滤波惯性导航中的卡尔曼滤波思想GNSS/INS
组合
导航分类松
组合
概念特点紧
组合
概念特点深
组合
概念特点GNSS/INS松
组合
观测方程(基础版)GNSS/INS松
组合
算法构建系统状态方程系统动态矩阵– F阵状态方程离散化– 状态转移矩阵状态方程离散化– 噪声等效离散化观测方程:GNSS位置更新GNSS位置更新观测方程:GNSS速度更新GNSS速度更新算法实现中的注意事项
组合
导航系统
组合
导航的概念 广义 任何两种及以上导航定位手段的
组合
◼交汇定位:G
【题解】【洛谷P1157】【子集枚举】——
组合
的
输出
蓝胖子编程教育,是一家面向青少年的编程教育平台。平台为全国青少年提供最专业的编程教育服务,包括提供最新最详细的编程相关资讯、最专业的竞赛指导、最合理的课程规划等。本平台利用趣味性和互动性强的教学方式,旨在激发孩子们对编程的兴趣,培养他们的逻辑思维能力和创造力,让孩子们在轻松愉快的氛围中掌握编程知识,为未来科技人才的培养奠定坚实基础。所有的
组合
,每一个
组合
占一行且其中的元素按由小到大的顺序排列,每个元素占三个字符的位置,所有的
组合
也按字典顺序。排列与
组合
是常用的数学方法,其中
组合
就是从。
组合
的
输出
(C++)
Description 排列与
组合
是常用的数学方法,其中
组合
就是从n个元素中抽出r个元素(不分顺序且r<=n),我们可以简单地将n个元素理解为自然数1,2,…,n,从中任取r个数。 现要求你用递归的方法
输出
所有
组合
。 例如n=5,r=3,所有
组合
为: l 2 3 l 2 4 1 2 5 l 3 4 l 3 5 1 4 5 2 3 4 2 3 5 2 4 5 ...
1317:【例5.2】
组合
的
输出
——全排列
组合
、
组合
选与不选
【题目描述】 排列与
组合
是常用的数学方法,其中
组合
就是从n个元素中抽出r个元素(不分顺序且r≤n),我们可以简单地将n个元素理解为自然数1,2,…,n,从中任取r个数。现要求你用递归的方法
输出
所有
组合
。例如n=5,r=3,所有
组合
为: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【输入】 一行两个自然数n、r(1...
数据结构与算法
33,025
社区成员
35,336
社区内容
发帖
与我相关
我的任务
数据结构与算法
数据结构与算法相关内容讨论专区
复制链接
扫一扫
分享
社区描述
数据结构与算法相关内容讨论专区
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章