c语言大数阶乘和计算阶乘末尾的0的个数
2015-06-06 00:20
766 查看
一、大数阶乘的数据保存
大数进行阶乘,将数据保存在数组中。这样遍历数组,就可以打印出阶乘的结果。
核心计算就是:将阶乘的乘法转化为加法和进位
比如:计算6!= 2*3*4*5*6 设为i
初始result[1]=1,result.length=1,carry默认是0
i = 2 -------->result[1]=(i*result[1])%10=2,carry=0,没产生进位,数组长度不增加,result[1]=2
i = 3 -------->result[1]=(i*result[1])%10=6,carry=0,没产生进位,数组长度不增加,result[1]=2
i = 4 -------->result[1]=(i*result[1])%10=24%10=4,carray=24/10=2,carry不为0,要产生进位,length++,此时result[1]=4,result[2]=0默认
result[2]=(i*result[2])%10=4*0+2=2,carry=0,此时,result[1]=4,result[2]=2
i = 5 -------->result[1]=(i*result[1])%10=4*5%10=0,carray=20/10=2,carry不为0,要产生进位,length++,此时result[1]=0,result[2]=2
result[2]=(i*result[2])%10=(5*2+2)%10=2,carry=1,此时,result[1]=0,result[2]=2 ,继续产生进位
result[3]=(i*result[3]%10)=5*0+1=1,carry=0,此时result[1]=0,result[2]=2,result[3]=1
那么倒序打印result数组,就是6!的值
代码
void BigFactorial(int targetNum)
{
static int a[50000]= {0,1}; //第一位不用
int carry = 0;//进位
int tmp = 0;//临时变量
int lenth=1;//已经保存的数组的长度
for(int i=2; i<=targetNum; i++) //外循环负责计算阶乘
{
carry=0;
for (int j=1; j<=lenth; j++) //内循环负责把阶乘的值保存到数组中
{
//乘法转化为加法和进位
tmp=a[j]*i+carry;
a[j]=tmp%10;
carry=tmp/10;
//如果有进位,则向前扩展一位
//内循环再计算一次
if (j==lenth&&carry!=0)
lenth++;
//如果没有产生进位,继续进行阶乘
}
}
for(int k=lenth; k>=1; k--)
printf("%d",a[k]);
}
int main()
{
BigFactorial(1000);
return 0;
}
二、计算一个数阶乘的值的末尾有多少个零?
1、首先考虑0的来源,来源与10
2、10可以分解为2*5,即只需要计算有多少对2*5,但2的倍数比5的倍数多,所以只需要计算5的倍数
int factorialof5(int i)
{
int count=0;
while(i % 5==0)
{
count++;
i /= 5;
}
return count;
}
int countOf0(int number)
{
int count=0;
for(int i = 2; i<=number; i++)
count += factorialof5(i);
return count;
}
//或者直接数5的因数
//从1到number之间,有几个5的倍数
大数进行阶乘,将数据保存在数组中。这样遍历数组,就可以打印出阶乘的结果。
核心计算就是:将阶乘的乘法转化为加法和进位
比如:计算6!= 2*3*4*5*6 设为i
初始result[1]=1,result.length=1,carry默认是0
i = 2 -------->result[1]=(i*result[1])%10=2,carry=0,没产生进位,数组长度不增加,result[1]=2
i = 3 -------->result[1]=(i*result[1])%10=6,carry=0,没产生进位,数组长度不增加,result[1]=2
i = 4 -------->result[1]=(i*result[1])%10=24%10=4,carray=24/10=2,carry不为0,要产生进位,length++,此时result[1]=4,result[2]=0默认
result[2]=(i*result[2])%10=4*0+2=2,carry=0,此时,result[1]=4,result[2]=2
i = 5 -------->result[1]=(i*result[1])%10=4*5%10=0,carray=20/10=2,carry不为0,要产生进位,length++,此时result[1]=0,result[2]=2
result[2]=(i*result[2])%10=(5*2+2)%10=2,carry=1,此时,result[1]=0,result[2]=2 ,继续产生进位
result[3]=(i*result[3]%10)=5*0+1=1,carry=0,此时result[1]=0,result[2]=2,result[3]=1
那么倒序打印result数组,就是6!的值
代码
void BigFactorial(int targetNum)
{
static int a[50000]= {0,1}; //第一位不用
int carry = 0;//进位
int tmp = 0;//临时变量
int lenth=1;//已经保存的数组的长度
for(int i=2; i<=targetNum; i++) //外循环负责计算阶乘
{
carry=0;
for (int j=1; j<=lenth; j++) //内循环负责把阶乘的值保存到数组中
{
//乘法转化为加法和进位
tmp=a[j]*i+carry;
a[j]=tmp%10;
carry=tmp/10;
//如果有进位,则向前扩展一位
//内循环再计算一次
if (j==lenth&&carry!=0)
lenth++;
//如果没有产生进位,继续进行阶乘
}
}
for(int k=lenth; k>=1; k--)
printf("%d",a[k]);
}
int main()
{
BigFactorial(1000);
return 0;
}
二、计算一个数阶乘的值的末尾有多少个零?
1、首先考虑0的来源,来源与10
2、10可以分解为2*5,即只需要计算有多少对2*5,但2的倍数比5的倍数多,所以只需要计算5的倍数
int factorialof5(int i)
{
int count=0;
while(i % 5==0)
{
count++;
i /= 5;
}
return count;
}
int countOf0(int number)
{
int count=0;
for(int i = 2; i<=number; i++)
count += factorialof5(i);
return count;
}
//或者直接数5的因数
//从1到number之间,有几个5的倍数
long long trailingZeros(long long n) { if(n<=0) return -1; long long count = 0; for(int i = 5;n/i>0;i*=5) count += n/i; return count; }
相关文章推荐
- C++中如何计算程序运行的时间
- 卫星照片
- C++函数可变参数实现原理探究——以实现printf为例
- c++的句柄
- 允许并列的排名
- C++指针与引用简析
- C语言使用函数递归判断栈的生长方向
- c语言循环链表的问题
- 关于头文件和库文件
- OpenCSP开源程序解析之OPENCSP_Mutex.cpp
- OpenCSP开源程序解析之OPENCSP_Main.cpp
- OpenCSP开源程序解析之OPENCSP_M*CSP.cpp
- OpenCSP开源程序解析之OPENCSP_Keyset.cpp
- OpenCSP开源程序解析之OPENCSP_Key.cpp
- 晚餐队列安排
- 【c++】堆排序算法
- OpenCSP开源程序解析之OPENCSP_Hash.cpp
- OpenCSP开源程序解析之OPENCSP_Alg.cpp
- 使用JsonCPP解析JSON数据 C++
- 关于C++类中的土著民:构造函数,复制构造函数,析构函数