哪里有排列组合方面的源程序?

yptang 2002-07-03 04:50:48
里有排列组合方面
...全文
66 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
alidiedie 2002-07-08
  • 打赏
  • 举报
回复
好多帖子有关这个,找一下了
yptang 2002-07-05
  • 打赏
  • 举报
回复
非常感谢!有无彩票方面排列组合源程序?旋转矩阵的算法?
one_add_one 2002-07-03
  • 打赏
  • 举报
回复
(转)
#ifndef _COMBINATION_H_
#define _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; // 记录组合数中每一位的可取值范围
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();
// 这是一个虚函数
// 可以在派生类中加入你自己的过滤器
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
{
if (LowBound[i] > L[i-1] + 1)
{
begin = LowBound[i];
}
else
{
begin = L[i-1] + 1;

}
}
for (int j = begin; j < = HighBound[i]; j++)
{

if (enabled[j]) {

enabled[j] = false;
L[i] = j;
SearchComb(i+1, L)
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;
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::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
下面是一个测试用的程序,可以测试上面的类
#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(arry[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(30, 7);
combs.SetBound(1, 4, 4);
combs.SetBound(2, 9, 9);
//combs.SetBound(3, 14, 14);
combs.SetBound(4, 26, 26);
combs.SetBound(5, 27, 27);
combs.SetBound(6, 29, 29);
combs.GenerateCombination();
cout < < "result is : " < < endl;
cout < < combs < < endl;
return 0;
}
非递归算法#include "stdio.h"
#include "iostream.h"
func(int n,char * a);
main()
{
char arr[]={65,66,67};
func(3,arr);
}
//language=c++
func(int n,char * a) //an array a[n]
{
int *i=new int[n];
int c=0,j;
i[c]=-1;
for(;i[0]< n;)
{
if(++i[c]< n)
{
for(j=0;j< c& & i[j]!=i[c];j++);
if(j==c)
{
if(c+1< n)
{
i[++c]=-1;
// continue;
}
else
{
for(int j=0;j< n;j++)
cout< < a[i[j]]< < ",";
cout< < endl;
}
}
}
else
c--;
}
}
one_add_one 2002-07-03
  • 打赏
  • 举报
回复
用STL
#include <algorithm>
#include <iostream>
int a[]={0,1,2,3,4,5,6,7};

int main(){
int i;
do{
for(i=0;i<sizeof(a)/sizeof(a[0]);i++)
cout<<a[i]<<' ';
cout<<'\n';
}while(next_permutation(a,a+sizeof(a)/sizeof(a[0])));
}

33,008

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧