`
宁辉522
  • 浏览: 15651 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

关于N的阶乘(n!)的java算法实现

    博客分类:
  • java
阅读更多
很多公司面试都会有一个问题,就是求N阶乘,主要是考查一些编程的基础知识如循环、类型的最大长度、递归等。

例如最简单的实现是:

public void factorial(int n){

long result = 1;

for(int i=0;i<n;i++){

  result = result*i;

}

}

但是,这个简单的实现可能会出现问题,   n一大就会超过long的最大值,从而导致错误。

而且随着n的增大,数会越来越大,即使是double也无法满足计算的需要。

为了解决这个问题,唯一的办法就是使用字符串,才能避免类型越界和数字大的问题,下面是基本的算法思路:

1)将数字用科学计数法表示,例如1234可以表示位1*1000+2*100+3*10+4*1

1000是10的3次方,100是10的2次方,10是10的1次方,1是10的0次方,依次类推。

2)两个多位数(10以上)相乘拆分成多次乘法,然后进行相加。

3)两个数相乘可以表示成两个数进行表示

4)用IntegerString[]数组表示一个数

程序如下:

定义类:

//表示一个数字,使用科学计数法。如500表示IntegerString(5,2)

public class IntegerString {
    private int number = 0;//数字
    private int length = 0;//10的length次方
    /** Creates a new instance of IntegerString */
    public IntegerString(int number,int length) {
        this.number = number;
        this.length = length;
    }
    public int getNumber(){
        return this.number;
    }
    public int getLength(){
        return this.length;
    }
}

/**

  两个数相乘,结果用两个数来表示,一个是高位,一个是低位

**/

public class MultiplyResult {
   
    private IntegerString high;
    private IntegerString low;
    /** Creates a new instance of MultiplyResult */
    public MultiplyResult(IntegerString a,IntegerString b) {
        int result = a.getNumber()*b.getNumber();
        int length = a.getLength()+b.getLength();
        if(result>=10){
            high = new IntegerString(result/10,length+1);
            low = new IntegerString(result%10,length);
        }else{
            high = new IntegerString(result,length);
            low = new IntegerString(0,length-1);
        }
    }
    public String toString(){ //打印方便,以便调试
        StringBuffer sb = new StringBuffer();
        sb.append(high.getNumber());
        sb.append(low.getNumber());
        for(int i=0;i<low.getLength();i++)
            sb.append("0");
        return sb.toString();
    }
    public IntegerString getHigh(){
        return high;
    }
    public IntegerString getLow(){
        return low;
    }
   
}

public class Factorial{

//由大到小,由高到低,将一个字符的数表示成科学计数法
private IntegerString[] getIntegerString(String str){
        IntegerString[] is = new IntegerString[str.length()];
        for(int i=0;i<str.length();i++){
            char ch = str.charAt(i);
            int number = Character.getNumericValue(ch);
            is[i] = new IntegerString(number,str.length()-1-i);
        }
        return is;
}

//获得数的最高位
    private int getMaxLength(IntegerString[] a){
        int max = 0;
        for(int i=0;i<a.length;i++){
            if(a[i].getLength()>max)
                max = a[i].getLength();
        }
        return max;
    }

    //一个数与单个数字相乘
    private IntegerString[] singleMultiply(IntegerString[] old,IntegerString gene){
        MultiplyResult[] mr = new MultiplyResult[old.length];
        for(int i=0;i<old.length;i++){
            mr[old.length-1-i] = new MultiplyResult(old[i],gene);
           // System.out.println(mr[old.length-1-i]);
        }
       
        //mr是从最低位到最高位
        java.util.ArrayList arrays = new java.util.ArrayList();
        int carry = 0;
        int maxLength = mr[mr.length-1].getHigh().getLength(); //获得最高位的长度
        for(int i=0;i<=maxLength;i++){//从个位到最高位一次加,如果有进位,那么存放到carry中
            int number = carry;
            for(int j=0;j<mr.length;j++){
               if(mr[j].getLow().getLength()==i)
               {
                   number+=mr[j].getLow().getNumber();
               }
               if(mr[j].getHigh().getLength()==i){
                   number+=mr[j].getHigh().getNumber();
               }  
            }
            if(number>=10){ //如果有进位,取余数,如果没有,取本身
                arrays.add(new IntegerString(number%10,i));
                carry=1;
            }else{
                arrays.add(new IntegerString(number,i));
                carry=0;
            }
        }
        if(carry==1){ //如果还有进位,那么加入到最高位
            arrays.add(new IntegerString(carry,maxLength+1));
        }
       IntegerString[] results = new IntegerString[arrays.size()];
       java.util.Iterator ii = arrays.iterator();
       int index=0;
       while(ii.hasNext()){
           results[index++] = (IntegerString)ii.next();
       }
       return results;
    }

    private void print(IntegerString[] a){
       System.out.println(getNumberic(a));
    }
    //将数字由IntegerString[]数组转换成字符串
    private String getNumberic(IntegerString[] a){
        StringBuffer sb = new StringBuffer();
        int max = getMaxLength(a);
        for(int i=0;i<=max;i++){
            boolean isFind = false;
            for(int j=0;j<a.length;j++){
                if(a[j].getLength()==i){
                    sb.insert(0,a[j].getNumber());
                    isFind = true;
                    break;
                }
            }
            if(!isFind){
                sb.insert(0,0);
            }
        }
        return sb.toString();
    }

    //两个数相加
    private IntegerString[] add(IntegerString[] a,IntegerString[] b){
        if(a==null) return b;
        if(b==null) return a;
       java.util.ArrayList arrays = new java.util.ArrayList();
       int aMax = getMaxLength(a);
       int bMax = getMaxLength(b);
       int max = aMax>bMax?aMax:bMax;
       int carry = 0;
       for(int i=0;i<=max;i++){
           
            for(int j1=0;j1<a.length;j1++){
                if(a[j1].getLength()==i)
                    carry+=a[j1].getNumber();
            }
            for(int j2=0;j2<b.length;j2++){
                 if(b[j2].getLength()==i)
                    carry+=b[j2].getNumber();
            }
            if(carry>0){
                if(carry>=10){
                    arrays.add(new IntegerString(carry%10,i));
                    carry=1;
                    if(i==max){
                        arrays.add(new IntegerString(carry,i+1));
                    }
                }else{
                    arrays.add(new IntegerString(carry,i));
                    carry=0;
                }
            }else{
                arrays.add(new IntegerString(0,i));
                carry=0;
            }
       }
       IntegerString[] results = new IntegerString[arrays.size()];
       java.util.Iterator ii = arrays.iterator();
       int index=0;
       while(ii.hasNext()){
           results[index++] = (IntegerString)ii.next();
       }
       return results;
    }

     //两个数相乘

     private String stringMultiply(String a,String b){
        IntegerString[] ais = this.getIntegerString(a);
        IntegerString[] bis = this.getIntegerString(b);
        IntegerString[] result = null;
        for(int i=0;i<bis.length;i++){
            IntegerString[] tmp = this.singleMultiply(ais,bis[i]);
            result = add(result,tmp);
        }
        return this.getNumberic(result);
    }

    //打印N的阶乘

    public void printFactorial(int n){

        String total = "1";
        int n=100;
        for(int i=1;i<=n;i++){
            total = stringMultiply(i+"",total);
        }

        System.out.println(total);

    }

}

使用此类计算的100的阶乘位:

93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000


此类也可以作为两个任意数字相乘,而且不会一越界。

以上算法可能存在的问题就是:

1)字符数组是以int位最大范围,可能超出界限,改进的方法是使用动态数组ArrayList

2)涉及到的算法含有大量的字符串操作,速度不是很快,当n=1000时,需要花费大量的时间,这点需要改进

3)如果N非常大,可能会造成内存不足的情况。
分享到:
评论

相关推荐

    java递归实现 阶乘

    在这个实例中,我们将深入探讨如何使用Java递归实现阶乘计算,并以1到10的数字为例进行演示。 阶乘是一个数学概念,表示一个正整数n的所有小于等于n的正整数的乘积,通常表示为n!。例如,5的阶乘(5!)是5 × 4 × ...

    n阶乘(n比较大时)

    然而,当我们谈论“n阶乘(n比较大时)”,这个问题就涉及到大数处理和计算效率。 在计算机科学中,尤其是编程语言中,实现大数阶乘会面临两个主要挑战:内存限制和计算时间。当n变得非常大时,n!的数值将超出常规...

    用java实现10000的阶乘(2种方法)

    本文将深入探讨如何使用Java语言实现计算10000的阶乘,我们将讨论两种不同的方法,每种方法都有其特定的时间复杂度和效率。 ### 方法一:递归计算 递归是最直观的解决阶乘问题的方法。基本思路是定义一个函数,...

    n的阶乘问题--阶乘位数--阶乘末尾0的个数

    在编程领域,阶乘是一个常见的数学概念,尤其在算法和计算数学中经常被用到。本文将深入探讨“n的阶乘问题”,包括阶乘的定义、计算阶乘位数的方法以及如何确定阶乘末尾零的个数。 首先,阶乘是指一个正整数n与小于...

    数据结构实习之n(n≥20)的阶乘

    6. **算法优化**:快速幂算法可以用于减少计算阶乘时的乘法次数,将n!表示为2的幂次和奇数的乘积,降低时间复杂度。 7. **错误处理**:处理负数或非整数输入,确保程序的健壮性。 8. **效率比较**:对比不同方法...

    阶乘与排列组合算法 各行各业都能用到

    在Java编程中,实现阶乘和排列组合计算可以使用循环或递归方法。例如,阶乘的递归实现如下: ```java public static int factorial(int n) { if (n == 0 || n == 1) { return 1; } else { return n * factorial...

    简单的java大数阶乘运算算法

    本篇将深入探讨如何利用Java实现大数阶乘的计算,以及背后的算法原理。 首先,我们需要了解阶乘的概念。阶乘是一个正整数n的所有小于等于n且大于0的正整数的乘积,表示为n!。例如,5! = 5 × 4 × 3 × 2 × 1 = ...

    java阶乘应用小程序

    在这个小程序中,我们将探讨如何使用JAVA来计算一个整数的阶乘,并进一步实现1到20所有整数阶乘的和。下面我们将深入讲解相关知识点。 首先,让我们了解什么是阶乘。阶乘是一个正整数n与小于它的所有正整数的乘积,...

    5!递归算法和非递归算法

    本文将详细介绍这两种算法的特点、应用场景以及如何实现它们,特别针对初学者及面试准备者。 #### 递归算法 递归算法是一种直接或间接调用自身的算法。其核心思想是将复杂问题分解为更小的子问题,直到这些子问题...

    Java计算阶乘 源代码

    本项目提供的"Java计算阶乘 源代码"旨在帮助我们实现任意整数的阶乘计算。首先,我们需要理解什么是阶乘。阶乘是将一个正整数n与小于它的所有正整数相乘的结果,表示为n!。例如,5! = 5 × 4 × 3 × 2 × 1 = 120。...

    JAVA实现各种算法

    在编程领域,算法是解决问题的关键,而Java作为一种广泛使用的编程语言,提供了丰富的工具和技术来实现各种算法。本文将深入探讨标题和描述中提及的几个重要算法:冒泡排序、递归算法、快速排序以及汉诺塔的实现。 ...

    Java算法之递归算法计算阶乘

    这个方法接受一个整数参数`n`,并使用递归的方式来实现。递归的基本思想是将大问题分解成小问题来解决。在这个例子中,大问题是如何计算阶乘,小问题是计算n-1的阶乘。 递归调用的终止条件是当`n`小于等于1时,返回...

    按照Java编码规范实现的阶乘算法

    本篇文章将详细讨论如何按照Java编码规范实现一个高效的阶乘算法。 首先,让我们理解什么是阶乘。阶乘是一个数学概念,表示一个正整数n与小于它的所有正整数的乘积,通常表示为n!。例如,5! = 5 × 4 × 3 × 2 × ...

    JAVA实现1到10的阶乘 ............

    ### JAVA实现1到10的阶乘 #### 知识点概述 本篇文章将详细介绍如何在Java编程语言中实现计算1到10的阶乘,并对给出的代码进行解析,帮助读者理解其工作原理以及相关的Java基础知识。 #### Java基础知识回顾 在...

    Java阶乘求和计算范例.rar

    在本示例中,我们关注的是使用Java编程语言来实现阶乘求和的计算过程。阶乘是一个数学概念,表示一个正整数n的所有小于等于n的正整数的乘积,通常用n!表示。例如,5!(5的阶乘)等于5 * 4 * 3 * 2 * 1 = 120。这个...

    能实现x^y和n!的计算器 Java

    ”的计算器项目中,我们看到一个Java程序,它不仅具备基础的四则运算功能,还特别实现了指数(x^y)计算和阶乘(n!)计算,这些都是数学运算中的重要组成部分。 指数运算x^y涉及到的是幂次方的问题,这是数学中的基本...

    递归算法(阶乘)

    在Java程序中,有两种常见的方法实现阶乘的计算:递归方式和循环方式。首先,让我们详细解析这两个方法: 1. 递归方式: `getDigui` 方法就是一个递归实现的例子。递归的核心思想是将大问题分解成小问题来解决。在...

    五的阶乘《java代码》

    在Java编程中,我们可以使用循环或递归的方式来实现阶乘的计算。以下是对这个话题的详细解释: 1. **Java基础** Java是一种多平台、面向对象的编程语言,由Sun Microsystems(现已被Oracle公司收购)于1995年发布...

    【JAVA】(vip)蓝桥杯试题 基础练习 阶乘计算 BASIC-30 JAVA

    问题描述是计算输入正整数n的阶乘n!,即1*2*3*...*n。为了处理大整数,可以使用数组A来存储每一位数字,A[0]为个位,A[1]为十位,以此类推。计算过程是将数组A中的每个元素乘以当前的数k,并处理进位。初始时,将A设...

    Java 编写的1到10的阶乘和

    在Java中实现阶乘的计算,可以为初学者提供基础的编程实践,理解循环和递归等概念。 在给定的"Java 编写的1到10的阶乘和"作业中,我们需要编写一个程序来计算1到10每个整数的阶乘,并将它们相加得到和。这个过程...

Global site tag (gtag.js) - Google Analytics