首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

请问关于彩票的组合绝对序号定位运行特慢的有关问题

2012-03-28 
请教关于彩票的组合绝对序号定位运行特慢的问题#ifndef Tdate_H#define Tdate_Hint comp(int m, int n){if

请教关于彩票的组合绝对序号定位运行特慢的问题
#ifndef Tdate_H
#define Tdate_H
int comp(int m, int n)
{
if (n>m)
return 0;
else if(m == n || n==0)
return 1;
else  
return comp(m-1,n)+comp(m-1,n-1);
}
#endif
上面是.H文件
extern "C" _declspec(dllexport) int JDXH(LYDATA *pData)
{
/*
红球绝对序号函数,
通过["RHx@JDXH"(n1)]调用
*/ 
int a,b,c,d,e,f;
a=pData->pCpData->nNum[1];
  b=pData->pCpData->nNum[2];
c=pData->pCpData->nNum[3];
d=pData->pCpData->nNum[4];
e=pData->pCpData->nNum[5];
f=pData->pCpData->nNum[6];  
int sum1 = 0;  
sum1 =comp(33,6)-comp(33-a+1,6)+comp(33-a,5)-comp(33-b+1,5)+comp(33-b,4)-comp(33-c+1,4)+comp(33-c,3)-comp(33-d+1,3)+comp(33-d,2)-comp(33-e+1,2)+comp(33-e,1)-comp(32-f+1,1);  
xh=sum1;
*pData->pfResult = xh;
return 1;
}
为什么这样运算特别慢?怎样修改写法呢?请老师们赐教,先谢谢了!(在VC6.0内弄的)
相关:http://topic.csdn.net/u/20080712/09/1d6df0ba-0f83-4c14-b4a1-ed396bb15a52.html?seed=1581837744&r=60480106#r_60480106

[解决办法]
你用加法递归的办法算组合不慢并且占CPU才怪。。。。
怎么计算组合高中知识把:C(m,n)=m*(m-1)*...*(m-n)/n!
[解决办法]
仅供参考

C/C++ code
//要求1:从给出来的不同的六组数字中,从每组任意挑选一个数字,最后组成一个六个数字的数组。//将所有的数组全部列出来。//同时,排除全部为偶数、全部为奇数的数组。//排除四个数字递增连续(比如8、9、10、11)的数组。//如下://第一个数字从这12个数字中挑选:,1,3,2,4,5,6,7,8,9,10,11,12//第二个数字从这17个数字中挑选:,8,7,5,9,6,4,11,10,12,13,3,14,17,2,16,15,18//第三个数字从这21个数字中挑选:,13,10,15,16,18,11,14,12,7,19,21,17,8,22,9,20,6,23,5,24,25//第四个数字从这20个数字中挑选:,22,23,18,20,16,17,15,21,14,26,19,24,27,25,12,13,11,10,28,29//第五个数字从这19个数字中挑选:,26,25,27,29,30,28,23,24,20,22,19,31,21,17,18,32,13,15,16//第六个数字从这14个数字中挑选:,32,33,30,31,29,28,27,26,25,24,23,22,18,21//要求2://请输入第1个数字的选择范围:(可以手动输入任意几个空格间隔的数字,最多30个)//请输入第2个数字的选择范围:(可以手动输入任意几个空格间隔的数字,最多30个)//请输入第3个数字的选择范围:(可以手动输入任意几个空格间隔的数字,最多30个)//请输入第4个数字的选择范围:(可以手动输入任意几个空格间隔的数字,最多30个)//请输入第5个数字的选择范围:(可以手动输入任意几个空格间隔的数字,最多30个)//请输入第6个数字的选择范围:(可以手动输入任意几个空格间隔的数字,最多30个)//然后回车,输出结果到cp.txt//要求3://保证同一组数据的数都不相同。//比如,第一个数为6时,第二个数或其他的数都不能再为6;第二个数为10时,第三个数或其他的数都不能再为10,以此类推……//要求4://增加一个条件:在产生的每个数组A1A2A3A4A5A6中,要求A1<A2<A3<A4<A5<A6#include <stdio.h>#include <stdlib.h>#include <string.h>int v[6];int n[6]={12,17,21,20,19,14};int d[6][30]={      {1,3,2,4,5,6,7,8,9,10,11,12},      {8,7,5,9,6,4,11,10,12,13,3,14,17,2,16,15,18},      {13,10,15,16,18,11,14,12,7,19,21,17,8,22,9,20,6,23,5,24,25},      {22,23,18,20,16,17,15,21,14,26,19,24,27,25,12,13,11,10,28,29},      {26,25,27,29,30,28,23,24,20,22,19,31,21,17,18,32,13,15,16},      {32,33,30,31,29,28,27,26,25,24,23,22,18,21},};int i,j,i0,i1,i2,i3,i4,i5,s;char ln[100],*t;FILE *f;int main() {    for (i=0;i<6;i++) {        printf("请输入第%d个数字的选择范围:",i+1);        fgets(ln,100,stdin);        j=0;        t=strtok(ln," ");        while (1) {            if (NULL==t) break;            if (0==t[0]) continue;//跳过多个空格间隔时取出的空串            d[i][j]=atoi(t);            j++;            if (j>=30) break;            t=strtok(NULL," ");        }        n[i]=j;    }    f=fopen("cp.txt","w");    if (NULL==f) {        printf("无法生成cp.txt!\n");        return 1;    }    printf("正在生成cp.txt...");    for (i0=0;i0<n[0];i0++) {    for (i1=0;i1<n[1];i1++) {    for (i2=0;i2<n[2];i2++) {    for (i3=0;i3<n[3];i3++) {    for (i4=0;i4<n[4];i4++) {    for (i5=0;i5<n[5];i5++) {        v[0]=d[0][i0];        v[1]=d[1][i1];        v[2]=d[2][i2];        v[3]=d[3][i3];        v[4]=d[4][i4];        v[5]=d[5][i5];        if (0==(v[0]%2)         && 0==(v[1]%2)         && 0==(v[2]%2)         && 0==(v[3]%2)         && 0==(v[4]%2)         && 0==(v[5]%2)) continue;//排除全部为偶数        if (1==(v[0]%2)         && 1==(v[1]%2)         && 1==(v[2]%2)         && 1==(v[3]%2)         && 1==(v[4]%2)         && 1==(v[5]%2)) continue;//排除全部为奇数        for (i=0;i<5;i++) {            for (j=i+1;j<6;j++) {                if (v[i]==v[j]) goto NEXT;//保证同一组数据的数都不相同            }        }    NEXT:        if (i>=5) {            for (i=0;i<5;i++) for (j=i+1;j<6;j++) if (v[i]>v[j]) {s=v[i];v[i]=v[j];v[j]=s;}//从小到大排序            if ((v[0]+1==v[1]              && v[1]+1==v[2]              && v[2]+1==v[3])             || (v[1]+1==v[2]              && v[2]+1==v[3]              && v[3]+1==v[4])             || (v[2]+1==v[3]              && v[3]+1==v[4]              && v[4]+1==v[5])) continue;//排除四个数字递增连续            fprintf(f,"%2d,%2d,%2d,%2d,%2d,%2d\n",v[0],v[1],v[2],v[3],v[4],v[5]);        }    }}}}}}    fclose(f);    printf("\n生成cp.txt完毕\n");    return 0;}//如果文件in.txt的内容为//1 3 2 4 5 6 7 8 9 10 11 12//8 7 5 9 6 4 11 10 12 13 3 14 17 2 16 15 18//13 10 15 16 18 11 14 12 7 19 21 17 8 22 9 20 6 23 5 24 25//22 23 18 20 16 17 15 21 14 26 19 24 27 25 12 13 11 10 28 29//26 25 27 29 30 28 23 24 20 22 19 31 21 17 18 32 13 15 16//32 33 30 31 29 28 27 26 25 24 23 22 18 21//可以在cmd窗口里面输入命令//cp <in.txt//得到要求1对应的结果//BTW:中了一定要分我六成啊!嘿嘿!(^=^) 


[解决办法]
因为楼主算法里用的都是double类型,有误差其实最后算出来是1105767.999999.。。。什么的,后边的省去了,就变成1105767了,你把算法中的double换成int试试
[解决办法]
int转double,用double计算完之后多半有误差,转int要+0.5四舍五入避免误差,但是不知道你这个算法是怎么搞这么复杂,明明简单的循环就搞定的
int comp(int m ,int n)
{
if (m<n)
return 0;
if (m==n)
return 1;
long long n1=1;
long long n2=1;
int i = 1;
for (i=1;i<=n;i++)
{
n1*=(i+m-n);
n2*=i;
}
return (n1/n2);
}
当然如果数很大要用到大数乘法,算法没做优化,但一般来说够用了
[解决办法]

探讨
int转double,用double计算完之后多半有误差,转int要+0.5四舍五入避免误差,但是不知道你这个算法是怎么搞这么复杂,明明简单的循环就搞定的
int comp(int m ,int n)
{
if (m<n)
return 0;
if (m==n)
return 1;
long long n1=1;
long long n2=1;
int i = 1;
for (……

热点排行
Bad Request.