大数的阶乘(网上的整理)

大数的阶乘

    众所周知,阶乘的定义就是n! = (n-1)!*n,但是有基本的初始条件的,即0! = 1

 因此1! = 1*0! = 1 * 1 = 1;

 2! = 2*1! = 2 * 1 = 2;

    依次类推,但是当n足够大时,整型根本无法装下n的阶乘,如果用C语言来实现的话,根本不可能,那怎么办呢?

其实阶乘也无非是乘法和加法罢了,如4!= 24;我们可以用数组来存各位,结舌数组的起始长度是1哈,每当遇到超过长度时,就自加1,不过这里要稍微处理下的,我们可以倒过来存,以便做乘法的,可以这样来存。

4!     4  2

5!   =  5 * 4!,可以用5去乘以4,如果大于10则需向高位进位,下一位的结果就等于下一位乘以5然后加上刚才的进位,当然也要取余数哈,然后继续看有没进位哈,知道遍乘数组每一位哈。

给个能求1000!的例子,用C语言实现的,供大家参考,以便交流学习哈。

#include <iostream>

using namespace std;

#define N 1000                 // 所需求的N的阶乘

static int a[N*3];            // 保存阶乘的各位

int main()

{

    int i,j;                  //临时变量

     int len = 1;

     int tem,carry;

     a[1] = 1;                  //1的阶乘

    for (i = 2;i<=N;i++)       //求阶乘的方法

    {

            carry = 0;

            for (j=1;j<=len;j++)

            {

                   tem = a[j]*i +carry;

                   a[j] = tem%10;

                   carry = tem/10;

                   if (j==len&&carry!=0)

                   {

                          len++;

                   }

            }

    

    }

     for (i = len;i>=1;i--) //输出各位

     {

            cout<<a[i];

     }

     cout<<endl;

     return 0;

}

我们也可以用Python来实现的哈,很简单两句话,就好啦

Import math

Math.factorial(1000)OK了,爽把!不过3.x以上的版本才有此函数哈。

    

     

 

 

 

 

JAVA

public class Factorial {

    public static void main(String[] args) {

        long start =System.currentTimeMillis();

        int i = 10000;

        BigInteger big = new BigInteger(Integer.toString(i));

        for (int j = i - 1; j > 1; j--) {

            big = big.multiply(new BigInteger(Integer.toString(j)));

        }

        long end = System.currentTimeMillis();

        System.out.println("run time: "+(end-start)+"ms");

        System.out.println(big.toString());

        System.out.println("show time: "+(System.currentTimeMillis()-end)+"ms");

    }

}

 

 

C#

 

10进制--> 1,000,000,000 进制

1000!阶乘0.048s 48ms (包含输出,以及每1000输出一次)

10000!阶乘5.553125s  5531.25ms (包含输出,以及每1000输出一次)

 

代码如下:

 

C# code

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.IO;

 

namespace Factorial

{

    class Program

    {

        static void Main(string[] args)

        {

            int Number = 0;

 

            //接收输入

            Console.WriteLine(@"Please input a numeric:");

            Number = int.Parse(Console.ReadLine().Trim());

 

            DateTime BeginTime = DateTime.Now;

            DateTime EndTime = DateTime.Now;

 

            //阶乘计算

            FactorialWithBaseNumberAndList.FactorialCalculation(Number);

 

            EndTime = DateTime.Now;

            Console.WriteLine(EndTime.Subtract(BeginTime).TotalMilliseconds + " ms!");

            Console.ReadKey();

        }

    }

}

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

namespace Factorial

{

    class FactorialWithBaseNumberAndList

    {

        public const ulong baseNumber = 1000000000;

        public static List<ulong> GetProduct(List<ulong> FactorX, List<ulong> FactorY)

        {

            List<ulong> ret = new List<ulong>();

            ulong Carry = 0;          //进位数

            ulong Product = 0;        //乘积

            int Position = 0;         //位数

            ulong Number = 0;         //乘积 % baseNumber 取余的余数

            ulong TempNumber = 0;     //旧值

 

            //循环历遍因数X中的元素

            for (int i = 0; i < FactorX.Count; i++)

            {

                //清除进位数

                Carry = 0;

                //循环历遍因数Y中的元素

                for (int j = 0; j < FactorY.Count; j++)

                {

                    //取得乘积,例如 9 * 9 = 81

                    Product = FactorX[i] * FactorY[j];

 

                    //取得位数,例如 因数X的第1 * 因数Y的第1,那么其乘积所在开始的位数则为2,

                    //比如 20 * 30 中两个十位数相乘其结果

                    //开始的位数为(2所在位数为1 + 3所在位数为1) = 6所在位数为2,即是600

                    Position = i + j;

                    //取得乘积 % baseNumber 取余的余数

                    Number = Product % baseNumber;

                    //判断乘积结果中该位是否有值,有值则相加,否则插入

                    if (ret.Count > Position)

                    {

                        //临时存放旧值

                        TempNumber = ret[Position];

                        //更新当前位的值,当前位值 = (旧值 + 取得乘积 % baseNumber 取余的余数 + 上一次进位数) % baseNumber 取余

                        ret[Position] = (TempNumber + Number + Carry) % baseNumber;

                        //取得当前进位值,當前進位值 = (旧值 + 乘积 + 进位)/baseNumber 取整

                        Carry = (ulong)Math.Floor((TempNumber + Product + Carry) / baseNumber * 1.0);

                    }

                    else

                    {

                        //插入位数,

                        ret.Add((Number + Carry) % baseNumber);

                        //取得当前进位值,當前進位值 = (乘积 + 进位)/10 取整

                        Carry = (ulong)Math.Floor((Product + Carry) / baseNumber * 1.0);

                    }

                }

                //当最后进位数不为0,需要新增最高位,其值为进位数

                if (Carry != 0) ret.Add(Carry);

            }

            return ret;

        }

 

        /// <summary>

        /// 阶乘计算

        /// </summary>

        public static void FactorialCalculation(int Number)

        {

            List<ulong> ProductZ = new List<ulong>(); //乘积Z - Dictionary

            List<ulong> FactorX = new List<ulong>();  //因数X - Dictionary

 

            //初始化乘积,避免出错

            ProductZ.Add(1);

 

            //阶乘数历遍,1开始

            for (int i = 1; i <= Number; i++)

            {

                //清空因数

                FactorX.Clear();

 

                //1000个数输出一次

                if (i % 1000 == 0) Console.WriteLine(i.ToString());

 

                FactorX.Add(Convert.ToUInt64(i));

 

                //计算乘积,将上一次的结果作为因数Y传入

                ProductZ = GetProduct(FactorX, ProductZ);

            }

 

            //显示结果

            ShowResult(ProductZ);

        }

 

        /// <summary>

        /// 显示结果

        /// </summary>

        /// <param name="Product">乘积 - List </param>

        /// <param name="DecimalDigits">小数位数 - int</param>

        public static void ShowResult(List<ulong> Product)

        {

            StringBuilder sb = new StringBuilder();

            for (int i = Product.Count - 1; i >= 0; i--)

            {

                sb.Append(Product[i]);

            }

            Console.WriteLine("Result:" + sb.ToString());

        }

    }

}

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/Lost_Painting/archive/2010/02/09/5302815.aspx

 

 

//-----------------------------------------------------------------------------  

//  

// 算法:阶乘类  

//  

// 版权所有(C) Snowdust  

// 个人博客    http://blog.csdn.net/snwodust & http://snowdust.cnblogs.com  

// MSN & Email snwodust77@sina.com  

//  

// 此源代码可免费用于各类软件(含商业软件)  

// 允许对此代码的进一步修改与开发  

// 但必须完整保留此版权信息  

//  

// 调用方法如下:  

// int num = 10000;  

// Arithmetic.Factorial f = new Arithmetic.Factorial(num);  

// List<int> result = f.Calculate();  

// String ret = f.ToString();  

// 返回结果:result100000进制表示的范型,ret为转换成十制制的字符串  

//  

// 版本历史:  

// V0.1 2010-03-17 摘要:首次创建   

//  

//-----------------------------------------------------------------------------  

 

using System;  

using System.Collections.Generic;  

using System.Text;  

 

namespace Arithmetic  

{  

    public class Factorial  

    { 

        #region 定义属性  

        /// <summary>  

        /// 进制  

        /// </summary>  

        private int m_BaseNumber = 100000;  

        public int BaseNumber  

        {  

            get 

            {  

                return m_BaseNumber;  

            }  

        }  

 

        /// <summary>  

        /// 待求阶乘的数  

        /// </summary>  

        private int m_Number;  

 

        /// <summary>  

        /// 结果  

        /// </summary>  

        private List<int> m_Result = new List<int>(); 

        #endregion 

 

        #region 构造函数  

        /// <summary>  

        /// 构造函数  

        /// </summary>  

        /// <param name="n">待求阶乘的数</param>  

        public Factorial(int n)  

        {  

            m_Number = n;  

            m_Result = new List<int>();  

        } 

        #endregion 

 

        #region 方法  

 

        /// <summary>  

        /// 计算阶乘  

        /// </summary>  

        /// <returns>结果范型</returns>  

        public List<int> Calculate()  

        {  

            int digit = (int)System.Math.Log10(m_BaseNumber);  

            int len = (int)(m_Number * System.Math.Log10((m_Number + 1) / 2)) / digit;//计算n!有数数字的个数   

            len += 2; //保险起见,加长2  

 

            int[] a = new int[len];  

            int i, j;  

            long c;  

            int m = 0;  

 

            a[0] = 1;  

            for (i = 2; i <= m_Number; i++)  

            {  

                c = 0;  

                for (j = 0; j <= m; j++)  

                {  

                    long t = a[j] * i + c;  

                    c = t / m_BaseNumber;  

                    a[j] = (int)(t % m_BaseNumber);  

                }  

                while (c > 0)   

                {  

                    m++;  

                    a[m] = (int)(c % m_BaseNumber);  

                    c = c / m_BaseNumber;  

                }  

            }  

            for (i = 0; i <= m; i++)  

            {  

                m_Result.Add(a[i]);  

            }  

            return m_Result;  

        }  

 

        /// <summary>  

        /// 重写ToString方法  

        /// </summary>  

        /// <returns>结果字符串</returns>  

        public override string ToString()   

        {  

            if (m_Result.Count == 0)  

            {  

                Calculate();  

            }  

            StringBuilder sb = new StringBuilder();  

            int digit = (int)System.Math.Log10(m_BaseNumber);  

            sb.Append(m_Result[m_Result.Count - 1]);  

            for (int i = m_Result.Count - 2; i >= 0; i--)  

            {  

                sb.Append(m_Result[i].ToString().PadLeft(digit, '0'));  

            }  

            return sb.ToString();  

        } 

        #endregion  

    }  

} 

 

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/Snowdust/archive/2010/03/18/5392444.aspx

 

C

#include<stdio.h>

#include<conio.h>

int arr[1000000]={0};

void mul(int arr[],int n,int *len)

{

int c=0,i,l=*len;

for(i=0;i<l;i++)

{

arr[i]=arr[i]*n+c;

c=arr[i]/10;

arr[i]%=10;

}

while(c!=0)

{

arr[l++]=c%10;

c/=10;

}

*len=l;

}

int main()

{

int i,n,len;

scanf("%d",&n);

len=1;arr[0]=1;

for(i=2;i<=n;i++)

mul(arr,i,&len);

for(i=len-1;i>=0;i--)

printf("%d",arr[i]);

printf("/n");

getch();

return 0;

}

 

 

 

C++

写的一个C++实现10000的阶乘的代码

#include<iostream>

#define N 10000//设阶乘数为10000

#define SIZE 40000//预留40000位保存结果

using namespace std;

void mul(int *n1,int n2)//两数相乘

{

for(int i=0;i!=SIZE;++i)

n1[i]*=n2;

for(int i=0;i!=SIZE;++i){

n1[i+1]+=(n1[i]/10);

n1[i]%=10;

}

}

int main()

{

int *num=new int[SIZE];

memset(num,0,SIZE);

num[0]=1;

//N的阶乘

for(int i=1;i!=N+1;++i){

mul(num,i);

}

//输出时排除开头的0

for(int i=SIZE-1;i!=-1;--i){

if(0!=num[i]){

for(int j=i;j!=-1;--j){

cout <<num[j];

}

break;

}

}

delete[] num;

return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值