主题:[原创]关于求任意数阶乘的算法
//factorial.h
/********************************************************************
* 文件名: factorial.h
* 文件描述: 求阶乘
* 创建人: 陈泽丹 ,2006年3月23日 (QQ:82314038)
* 版本号: 1.0
* 修改记录:
********************************************************************/
/*============================================================
自定义类型(ElemType) : double
类名: Factorial
- x: ElemType
- next: Factorial*
//执行进位的操作
- carry(Factorial* &c, ElemType xx): ElemType
//显示结果的重载函数
- display(Factorial* t): void
//格式化显示结果
- format(ElemType xx,int count): void
//构造函数防止next越界
+ Factorial():x(0),next(NULL){}
//设置类的初始值
+ set(ElemType xx): void
//执行乘法运算
+ M(ElemType xx): void
//显示结果
+ display(): void
//显示结果的位数
+ digit(): double
作 者:陈泽丹 2006/3/23
============================================================*/
/* --------------------------------------------------------------------
补充:
1, 以下CARRY与DIGIT的更新需同步,
2, 以下CARRY与DIGIT值越大,效率越高风险越大
3, 以下CARRY与DIGIT值越低,效率越差风险越小
4, 为合理利用空间,本程序采用动态分配的方案,故若阶乘数太大,请注意你的
内存问题。
(解释:由于进位的堆积,如某数据段一万乘一万,进位后又刚好与下一个本身
就很大数据段的数据堆积一起,于是“突围了”。。。,所以越后面越有数据
段范围崩溃危险,改良方法是每一个数据段“递归”或改“类乘类(而非本例的'类乘
实数')”,不过这就不是此文三言两语说得清的了。另外,即使数据段定位再小也有风
险,另忘了数值小点的数乘大数还是可成大数的。)
----------------------------------------------------------------------*/
#ifndef HEADER_FACTORIAL
#define HEADER_FACTORIAL
#include <iostream.h>
#define ElemType double
#define CARRY 1000 //进位的条件
#define DIGIT 3 //数据段的位数
class Factorial
{
private:
ElemType x;
Factorial* next;
ElemType carry(Factorial* &c, ElemType xx);
void display(Factorial* t);
void format(ElemType xx,int count);
public:
Factorial():x(0),next(NULL){}
void set(ElemType xx);
void M(ElemType xx);
void display();
double digit();
};
#endif
/*======================================================================*/
//factorial.cpp
//factor类实现部份
#include "factorial.h"
void Factorial::set(ElemType xx)
{
x=xx;
Factorial *t=this;
while (t != NULL)
{
if ( t->x > CARRY)
{
t->x=carry(t->next,t->x);
}
t=t->next;
}
}
void Factorial::M(ElemType xx)
{
Factorial *t=this;
while (t!=NULL)
{
t->x*=xx;
t=t->next;
}
t=this;
while (t != NULL)
{
if ( t->x > CARRY)
{
t->x=carry(t->next,t->x);
}
t=t->next;
}
}
ElemType Factorial::carry(Factorial* &c, ElemType xx)
{
if ( c==NULL)
{
c= new Factorial;
c->next=NULL;
}
int temp=xx/CARRY;
c->x=c->x+temp;
return xx-temp*CARRY;
}
void Factorial::display()
{
display(this);
}
void Factorial::display(Factorial *t)
{
if (t!=NULL)
{
display(t->next);
if (t->next!=NULL) { format(t->x,DIGIT); }
else cout<<t->x;
if (t != this) cout<<",";
}
}
void Factorial::format(ElemType xx, int count)
{
if (count>0)
{
int temp=xx;
format(xx/10,count-1);
cout<<temp%10;
}
}
double Factorial::digit()
{
Factorial *t=this;
double i=0;
while(t->next!=NULL)
{
i+=1;
t=t->next;
}
int d=0;
int temp=t->x;
while(temp)
{
d++;
temp=temp/10;
}
return i*DIGIT+d;
}
/*=================================================================*/
//Main.cpp
//主函数实现部份
#include "factorial.h"
#include "iostream.h"
void main()
{
Factorial c;
ElemType start, end;
cout<<"本程序实现连乘效果(阶乘是连乘的特例)"<<endl;
cout<<"请输入起始数:";
cin>>start;
c.set(start);
cout<<"您输入的的起始数为";
c.display();
cout<<endl;
cout<<"请输入终止数: ";
cin>>end;
for (int i=start+1;i<=end; i++) { c.M(i); }
c.display();
cout<<endl;
cout<<"共有"<<c.digit()<<"位"<<endl;
}
/********************************************************************
* 文件名: factorial.h
* 文件描述: 求阶乘
* 创建人: 陈泽丹 ,2006年3月23日 (QQ:82314038)
* 版本号: 1.0
* 修改记录:
********************************************************************/
/*============================================================
自定义类型(ElemType) : double
类名: Factorial
- x: ElemType
- next: Factorial*
//执行进位的操作
- carry(Factorial* &c, ElemType xx): ElemType
//显示结果的重载函数
- display(Factorial* t): void
//格式化显示结果
- format(ElemType xx,int count): void
//构造函数防止next越界
+ Factorial():x(0),next(NULL){}
//设置类的初始值
+ set(ElemType xx): void
//执行乘法运算
+ M(ElemType xx): void
//显示结果
+ display(): void
//显示结果的位数
+ digit(): double
作 者:陈泽丹 2006/3/23
============================================================*/
/* --------------------------------------------------------------------
补充:
1, 以下CARRY与DIGIT的更新需同步,
2, 以下CARRY与DIGIT值越大,效率越高风险越大
3, 以下CARRY与DIGIT值越低,效率越差风险越小
4, 为合理利用空间,本程序采用动态分配的方案,故若阶乘数太大,请注意你的
内存问题。
(解释:由于进位的堆积,如某数据段一万乘一万,进位后又刚好与下一个本身
就很大数据段的数据堆积一起,于是“突围了”。。。,所以越后面越有数据
段范围崩溃危险,改良方法是每一个数据段“递归”或改“类乘类(而非本例的'类乘
实数')”,不过这就不是此文三言两语说得清的了。另外,即使数据段定位再小也有风
险,另忘了数值小点的数乘大数还是可成大数的。)
----------------------------------------------------------------------*/
#ifndef HEADER_FACTORIAL
#define HEADER_FACTORIAL
#include <iostream.h>
#define ElemType double
#define CARRY 1000 //进位的条件
#define DIGIT 3 //数据段的位数
class Factorial
{
private:
ElemType x;
Factorial* next;
ElemType carry(Factorial* &c, ElemType xx);
void display(Factorial* t);
void format(ElemType xx,int count);
public:
Factorial():x(0),next(NULL){}
void set(ElemType xx);
void M(ElemType xx);
void display();
double digit();
};
#endif
/*======================================================================*/
//factorial.cpp
//factor类实现部份
#include "factorial.h"
void Factorial::set(ElemType xx)
{
x=xx;
Factorial *t=this;
while (t != NULL)
{
if ( t->x > CARRY)
{
t->x=carry(t->next,t->x);
}
t=t->next;
}
}
void Factorial::M(ElemType xx)
{
Factorial *t=this;
while (t!=NULL)
{
t->x*=xx;
t=t->next;
}
t=this;
while (t != NULL)
{
if ( t->x > CARRY)
{
t->x=carry(t->next,t->x);
}
t=t->next;
}
}
ElemType Factorial::carry(Factorial* &c, ElemType xx)
{
if ( c==NULL)
{
c= new Factorial;
c->next=NULL;
}
int temp=xx/CARRY;
c->x=c->x+temp;
return xx-temp*CARRY;
}
void Factorial::display()
{
display(this);
}
void Factorial::display(Factorial *t)
{
if (t!=NULL)
{
display(t->next);
if (t->next!=NULL) { format(t->x,DIGIT); }
else cout<<t->x;
if (t != this) cout<<",";
}
}
void Factorial::format(ElemType xx, int count)
{
if (count>0)
{
int temp=xx;
format(xx/10,count-1);
cout<<temp%10;
}
}
double Factorial::digit()
{
Factorial *t=this;
double i=0;
while(t->next!=NULL)
{
i+=1;
t=t->next;
}
int d=0;
int temp=t->x;
while(temp)
{
d++;
temp=temp/10;
}
return i*DIGIT+d;
}
/*=================================================================*/
//Main.cpp
//主函数实现部份
#include "factorial.h"
#include "iostream.h"
void main()
{
Factorial c;
ElemType start, end;
cout<<"本程序实现连乘效果(阶乘是连乘的特例)"<<endl;
cout<<"请输入起始数:";
cin>>start;
c.set(start);
cout<<"您输入的的起始数为";
c.display();
cout<<endl;
cout<<"请输入终止数: ";
cin>>end;
for (int i=start+1;i<=end; i++) { c.M(i); }
c.display();
cout<<endl;
cout<<"共有"<<c.digit()<<"位"<<endl;
}