排列組合的算法!

kirao 2004-10-18 04:57:03

 福利彩票37選7,實現從37個號碼中選8-37個號碼(也就是復式投注法)
 
 利用電腦算出它一共有多少什麼樣的組合。

 如我輸入9個數,它會顯示出這9個數中選7個時各種組合是什麼。
...全文
258 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
malligator 2004-10-21
  • 打赏
  • 举报
回复
没啥。
大家都互相学习嘛
要过意不去另开个帖给我们哈
:)
kirao 2004-10-21
  • 打赏
  • 举报
回复

  謝謝各位,謝謝 malligator(大螟)
  
  可惜分放得太少。。。。。。。
malligator 2004-10-20
  • 打赏
  • 举报
回复
回复人: hcj2002(流浪者·躬自厚而薄责于人) (毕业ING & 找工作ING
http://community.csdn.net/Expert/topicview.asp?id=2346927

^_^
回复人: cxjddd(又是花开时)
http://community.csdn.net/Expert/topic/3143/3143703.xml?temp=.2978632

--------------------
有收获,谢谢!
有空我在研究研究
malligator 2004-10-20
  • 打赏
  • 举报
回复
5选3:
数组number中的值 选中的号码
1 1 1 0 0 (初始化) 1, 2 ,3
1 1 0 1 0 1 2 4
1 0 1 1 0 1 3 4
0 1 1 1 0 2 3 4
1 1 0 0 1 1 2 5
1 0 1 0 1 1 3 5
0 1 1 0 1 2 3 5
1 0 0 1 1 1 4 5
0 1 0 1 1 2 4 5
0 0 1 1 1 (全部移到右边,结束)3 4 5
hcj2002 2004-10-20
  • 打赏
  • 举报
回复
http://community.csdn.net/Expert/topicview.asp?id=2346927

^_^
malligator 2004-10-20
  • 打赏
  • 举报
回复
由于本人机器不是很好,测试只是测试了m<25的数据(24选7该有346104种选法,
我执行了好些时间才完);本程序理论上能满足37选7的要求(自己改动一下m,n 就行了)。
又,注意:24选7时数据是刚才我用计算器求出来的,程序里没有显示正确,
整数已经溢出了。
----------------------------------------------
下面说一下算法:
用数组number纪录被选中的元素(等于1 时表示被选中,其下标+1 就是楼主要求选的号码。)
初始化选中前n 个号码,即1,2,......,n。对应下标为0,1,.....,n-1。
然后把紧挨着的最左边的1,0换位置,同时被换位置的1 的左边的1 全部移到最左边,
如此反复,直到所有的1 都被移到最右边,此时为m-n+1 到m 这n 个元素被选中。
下面用5选3 为例说明number 中1,0的移动方式:
1 1 1 0 0 (初始化)
1 1 0 1 0
1 0 1 1 0
0 1 1 1 0
1 1 0 0 1
1 0 1 0 1
0 1 1 0 1
1 0 0 1 1
0 1 0 1 1
0 0 1 1 1 (全部移到右边,结束)
malligator 2004-10-20
  • 打赏
  • 举报
回复
由于本人机器不是很好,测试只是测试了m<25的数据(24选7该有346104种选法,
我执行了好些时间才完);本程序理论上能满足37选7的要求(自己改动一下m,n 就行了)。
又,注意:24选7时数据是刚才我用计算器求出来的,程序里没有显示正确,
整数已经溢出了。
----------------------------------------------
下面说一下算法:
用数组number纪录被选中的元素(等于1 时表示被选中,其下标+1 就是楼主要求选的号码。)
初始化选中前n 个号码,即1,2,......,n。对应下标为0,1,.....,n-1。
然后把紧挨着的最左边的1,0换位置,同时被换位置的1 的左边的1 全部移到最左边,
如此反复,直到所有的1 都被移到最右边,此时为m-n+1 到m 这n 个元素被选中。
下面用5选3 为例说明number 中1,0的移动方式:
1 1 1 0 0 (初始化)
1 1 0 1 0
1 0 1 1 0
0 1 1 1 0
1 1 0 0 1
1 0 1 0 1
0 1 1 0 1
1 0 0 1 1
0 1 0 1 1
0 0 1 1 1 (全部移到右边,结束)
cxjddd 2004-10-20
  • 打赏
  • 举报
回复
http://community.csdn.net/Expert/topic/3143/3143703.xml?temp=.2978632
malligator 2004-10-20
  • 打赏
  • 举报
回复
C语言版本(从C++改成C不是很难啊),后边说一下算法。
-------------------------------------------------
/*TC 2.0 */
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>

int number[50]; /*最多求50个数的组合。 */
int m=24,n=7; /* 2<=m<=50,n<m ,自己可以改动 */
const false=0,true=1;

void inition() /*初始化*/
{
int i;
for(i=0;i<n;i++)
number[i]=1;
}

void output() /*输出组合结果*/
{
int i;
for(i=0;i<m;i++)
if(number[i])
printf("%3d",(i+1));
printf("\n");
}

void main()
{
long count=0; /*计数组合个数 */
int i,j,k,l;
int findfirst,end=false,swap;
inition(); /*初始化 */
output(); /*结果输出*/
count++;
j=m;
while(!end)
{
findfirst=false;
swap=false; /*标志复位*/
for(i=0;i<j;i++)
{
if(!findfirst && number[i])
{
k=i; /*k记录下扫描到的第一个数*/
findfirst=true; /*设置标志 */
}
if(number[i] && !number[i+1]) /*从左到右扫描第一个“10”组合*/
{
number[i]=0;
number[i+1]=1;
swap=true; /*设置交换标志 */
for(l=0;l<i-k;l++)
number[l]=number[k+l];
for(l=i-k;l<i;l++)
number[l]=0; /*交换后将之前的“1”全部移动到最左端 */
if(k==i && i+1==m-n) /*如果第一个“1”已经移动到了m-n的位置,说明*/
/* //这是最后一个组合了。 */
end=true;
}
if(swap) /*交换一次后就不用继续找“10”组合了 */
break;
}
output(); /*结果输出 */
count++; /*组合数计数器递增1 */
}
printf("total number of combination is: %d \n",count); /*打印总的组合数*/
printf("press any key to continue!\n");
getch();
}
kirao 2004-10-19
  • 打赏
  • 举报
回复
to:malligator(大螟)

我沒學過c++,你的程序有些地方看不懂,有沒有用c寫的,給基本算法就好了。
zhang_yale 2004-10-18
  • 打赏
  • 举报
回复
to:malligator(大螟)
你的程序可能可以完成这个任务,但是我觉得可读性不是很好,主函数太长,这好象不是C++所提倡的吧
malligator 2004-10-18
  • 打赏
  • 举报
回复
这是我在另一个帖:
http://community.csdn.net/Expert/topic/3463/3463523.xml?temp=.567135
回复的。
现在没有时间,楼主自己改一下就行了。
附:
直接调用也行,就是要求把数组a[n]的元素值自己输入为1--n 就可以了。
这么就不太好,因为取37的时候b[][n]太大了。
(n==37,k==7时要40多兆内存空间呢)
我机器是192M内存的,再加上输出花挺多时间,运行起来比较慢了
malligator 2004-10-18
  • 打赏
  • 举报
回复
//我写的,应该能满足要求。这主要是完成n 个元素取k 个的功能
//如果单单这个问题看,二维数组b[][]就没有必要了
//本程序需要输入的数组元素在本题目中由于是1-37递增有序,
//可以直接取数组number[]的下标就行了(可以把关于
//数组a[]的都删掉,用到的代之以number[]的下标)。

#include<iostream.h>
#include<stdlib.h>
#include<conio.h>
#include<iomanip.h>

void inition(int k,int number[]) //初始化
{
int i;
for(i=0;i<k;i++) //一开始先选定前k 个元素
number[i]=1;
}

void output(int a[],int n,int number[],int **b,int count)
//输出一种组合结果
{
int i,k=0;
for(i=0;i<n;i++)
if(number[i]){
b[count][k]=a[i];
k++;
cout<<setw(3)<<a[i];
}
cout<<endl;
}

void main()
{
int count=0; //计数组合个数
int n=6,k=4,size=15,i,j,l,m;
int number[100]={0}; //辅助数组,纪录被选中的元素
//这里定义最多元素为100
int *a;
int **b;
bool findfirst,end=false,swap;

cout<<"please input n:"<<endl;
cin>>n; //输入数组大小n
a=new int[n];
cout<<"please input elem of a:"<<endl;
for(i=0;i<n;i++)
cin>>a[i]; //输入数组元素
cout<<"please input k(<n):"<<endl;
cin>>k; //输入m
size=1;
for(i=0,j=n;i<k;i++)
size*=j--;
for(i=1;i<=k;i++)
size/=i;
b=new int*[size]; //分配保存结果的二维数组
for(i=0;i<size;i++)
b[i]=new int[k];
inition(k,number); //初始化
output(a,n,number,b,count);
count++; //第一组结果输出
j=n;
while(!end)
{
findfirst=false;
swap=false; //标志复位
for(i=0;i<j;i++)
{
if(!findfirst && number[i])
{
l=i; //l 记录下扫描到的第一个数
findfirst=true; //设置标志
}
if(number[i] && !number[i+1]) //从左到右扫描第一个“10”组合
{
number[i]=0;
number[i+1]=1;
swap=true; //设置交换标志
for(m=0;m<i-l;m++)
number[m]=number[m+l];
for(m=i-l;m<i;m++)
number[m]=0; //交换后将之前的“1”全部移动到最左端
if(l==i && i+1==n-k) //如果第一个“1”已经移动到了m-n
end=true; //的位置,说明这是最后一个组合了。

}
if(swap) //交换一次后就不用继续找“10”组合了
break;
}
output(a,n,number,b,count);
count++;
}
cout<<"total number is: "<<count<<endl; //打印总的组合数

getch();
}
kirao 2004-10-18
  • 打赏
  • 举报
回复
如我有 1,2,3,4如果我選擇其中3個數,則有如下排列

 1 2 3
1 2 4
1 3 4
2 3 4
.

kirao 2004-10-18
  • 打赏
  • 举报
回复
to kobefly(科比)
你的程序是排列組合的問題,我要的僅是組合,沒有排列,所以有很多重復,不是我想要的!
whoho 2004-10-18
  • 打赏
  • 举报
回复
看看标准库中的next_permutation等几个关于排列的算法
源代码里面给出的算法比穷举好得多]
寻开心 2004-10-18
  • 打赏
  • 举报
回复
c(n,m)的算法
你只是选择7个而已
那么做个7重的循环
例如
int max = 9; // 表示有多少个代选数字
char * pChar = new char[max];  // 保存代选的数字

for ( int i1=1; i1<max-6; i1++ )
for (int i2=i1+1; i2<max-5; i2++ )
for (int i3=i2+1; i2<max-4; i3++ )
for (int i4=i3+1; i2<max-3; i4++ )
for (int i5=i4+1; i2<max-2; i5++ )
for (int i6=i5+1; i2<max-1; i6++ )
for (int i7=i6+1; i2<max; i7++ )
printf("%02d %02d %02d %02d %02d %02d %02d", i1, i2, i3, i4, i5, i6, i7);
kobefly 2004-10-18
  • 打赏
  • 举报
回复

全排列的例子
#include<stdio.h>

#define MAXN 100
int a[MAXN] = {0};
int flag[MAXN] = {0};

void comb(int m, int k, int s)
{
int i;

if (s >= k)
{
for (i = 0; i < k; i++)
{
printf("%d",a[i]);
}
printf("\n");
}
else
{
for (i = 1; i <= m; i++)
if (0 == flag[i])
{
flag[i]=1;
a[s]=i;
comb(m,k,s+1);
a[s]=0;
flag[i]=0;
}
}
}

void main()
{
int i;
int m,n;
char index;
while(1)
{
printf("输入m的值:\n");
scanf("%d",&m);
fflush(stdin);
printf("输入n的值:\n");
scanf("%d",&n);
fflush(stdin);
for (i=0; i<MAXN; i++)
{
flag[i]=0;
a[i]=flag[i];
}

comb(m,n,0);

printf("还要继续么?[Y/N]\n");
scanf("%c",&index);
fflush(stdin);
if(index == 'n'||index == 'N')
break;
}
//comb(m,n,0) 表示求m个选n个的排列
}

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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