- 注册时间
- 2007-12-28
- 最后登录
- 1970-1-1
- 威望
- 星
- 金币
- 枚
- 贡献
- 分
- 经验
- 点
- 鲜花
- 朵
- 魅力
- 点
- 上传
- 次
- 下载
- 次
- 积分
- 12785
- 在线时间
- 小时
|
发表于 2019-4-17 20:07:00
|
显示全部楼层
5#的第三个条件,理由不充分。去掉。
修改后的代码如下:
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- typedef struct _node
- {
- double logp; // log(p)
- double logn; // 高度合成数的对数,是累加的
- int e; // 指数
- double fn; // 因子总数,
- }NODE;
- #define MAX_D 32 //最大深度为32,最大可查找具有32个素因子的高度合成数
- //前32个素数
- const int sp[MAX_D]=
- {
- 2, 3, 5, 7, 11, 13, 17, 19,
- 23, 29, 31, 37, 41, 43, 47, 53,
- 59, 61, 67, 71, 73, 79, 83, 89,
- 97, 101, 103, 107, 109, 113, 127, 131
- };
- // 更新 arr[n], arr[n-1], 直到arr[1]
- void init( NODE arr[], int n )
- {
- int i;
- for (i=n;i>=1;i--)
- {
- arr[i].logp= log( (double)sp[i-1]); arr[i].e=1;
- if (i==n)
- {
- arr[i].logn= arr[i].logp * arr[i].e;
- arr[i].fn = arr[i].e+1;
- }
- else
- {
- arr[i].logn= arr[i+1].logn + (arr[i].logp * arr[i].e); // arr[1].logn 就是这个数的对数
- arr[i].fn = arr[i+1].fn * (arr[i].e+1); //这个累计的,arr[1].fn就是这个数的所有因子数
- }
- }
- }
- // arr[pos].e++;
- // arr[j].e= arr[pos].e ( 1<=j<pos)
- // 进位不溢出,返回true, 否则返回false
- // m 为最大查找深度
- bool carry( NODE arr[], int pos , int m, double maxLogN)
- {
- while (1)
- {
- if ( pos>m)
- return false;
- arr[pos].e++;
- if ( pos<m)
- {
- arr[pos].logn = arr[pos+1].logn + (arr[pos].logp * arr[pos].e);
- arr[pos].fn = arr[pos+1].fn * (arr[pos].e+1);
- }
- else // pos==m
- {
- arr[pos].logn = (arr[pos].logp * arr[pos].e);
- arr[pos].fn = (arr[pos].e+1);
- }
- for (int i=pos-1;i>=1;i--)
- {
- arr[i].e = arr[pos].e;
- arr[i].logn = arr[i+1].logn + (arr[i].logp * arr[i].e); // arr[1].logn 就是这个数的对数
- arr[i].fn = arr[i+1].fn * (arr[i].e+1); //这个累计的,arr[1].fn就是这个数的所有因子数
- }
-
- if ( arr[1].logn < maxLogN )
- break;
- pos++; // 在arr[pos]处做进位失败,继续在更高位上做进位
- }
- return true;
- }
- void saveResult(NODE arr[], int eArr[], int m, double *pMaxFac)
- {
- if ( arr[1].fn > *pMaxFac)
- {
- for (int j=1;j<=m;j++)
- eArr[j]=arr[j].e; //保存结果
- *pMaxFac= arr[1].fn;
- }
- }
- void print_factor_list(int eArr[], int m )
- {
- double fac=1.0; //因子数
- printf("\n");
- for (int i=m;i>=1;i--)
- {
- fac *= (eArr[i]+1.0);
- if ( eArr[i]==1)
- printf("%d",sp[i-1]);
- else
- printf("(%d^%d)", sp[i-1], eArr[i]);
- if ( i>1)
- printf("*");
- }
- printf(",%lf factor\n",fac);
- }
- // 查找高度合成数
- // eArr为各个素因子的指数,m为查找深度,返回最佳搜索结果的因子的个数,eArr[]存放因子
- // arr[0]和eArr[0]不使用
- double search_HCN( NODE arr[], int eArr[], double maxLogN, int m )
- {
- double maxFac=0.0; // 最大因子数
- init(arr,m);
- if ( arr[1].logn<maxLogN) //第一个搜索的组合就超范围,返回0.0
- saveResult(arr, eArr, m, &maxFac);
- else
- {
- for (int i=1;i<=m;i++)
- eArr[i]=0;
- return 0.0;
- }
- while (1)
- {
- // 将arr[1].e增加
- arr[1].e++;
- arr[1].logn = arr[2].logn + (arr[1].logp * arr[1].e); // arr[1].logn 就是这个数的对数
- arr[1].fn = arr[2].fn * (arr[1].e+1);
-
- if (arr[1].logn < maxLogN)
- saveResult(arr, eArr, m, &maxFac); //保存结果
- else
- {
- if ( carry( arr, 2, m, maxLogN) ) //进位成功
- saveResult(arr, eArr, m, &maxFac);
- else
- break; //进位失败,所有搜索完成
- }
- }
- return maxFac; //返回最大因子个数
- }
- void test_search_hcn()
- {
- NODE arr[MAX_D+1] ;
- int eArr[MAX_D];
- double logMaxN= log(2.0) + log(10.0)*40; //高度合查成数的对数不能超过max
- double sum;
- int i,maxDeep; //最大查找深度
-
- for (sum=0.0,i=0;i<MAX_D;i++)
- {
- sum += log( (double)(sp[i]));
- if (sum<logMaxN)
- maxDeep=i+1;
- else
- break;
- }
- for (int m=maxDeep; m>=2;m--) //查找素因子个数为m,m-1,..,3,2的情况下的高度合成数
- {
- search_HCN( arr, eArr, logMaxN, m );
- print_factor_list(eArr,m);
- }
- }
- int main(int argc, char* argv[])
- {
- test_search_hcn();
- return 0;
- }
复制代码 |
|