请教关于彩票的组合绝对序号定位运行特慢的问题
#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!
[解决办法]
仅供参考
//要求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);
}
当然如果数很大要用到大数乘法,算法没做优化,但一般来说够用了
[解决办法]