求编个java程序要求:编写一个求大数的阶乘,不能用biginteger,并且使用数组不能浪费,不

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了求编个java程序要求:编写一个求大数的阶乘,不能用biginteger,并且使用数组不能浪费,不相关的知识,希望对你有一定的参考价值。

求编个java程序要求:编写一个求大数的阶乘,不能用biginteger,并且使用数组不能浪费,不能有空位,输出计算时间,结果和结果的位数。另外有5Q的奖励!

做毕业设计用的吧?我两年前帮哥们写过一个,乘法加法和一些简单的用法都写好了。照着这个改改就行了

public class MyBigInt 
    public static final int[] ten =  10 ;
    public static final int[] zero =  0 ;
    public static final int[] one =  1 ;
    int[] myInt;

    public int[] getMyInt() 
        return myInt;
    

    public void setMyInt(int[] myInt) 
        this.myInt = myInt;
    

    public MyBigInt() 
        myInt = zero;
    

    public MyBigInt(String a) 
        myInt = new int[a.length()];
        for (int i = 0; i < myInt.length; i++) 
            myInt[i] = Integer.parseInt(String.valueOf(a.charAt(myInt.length
                    - i - 1)));
        
    

    public MyBigInt chengFa(MyBigInt myBigInt) 
        int[] myIntA = myInt;
        int[] myIntB = myBigInt.getMyInt();
        int a, b;
        int s = 0;
        int c = 0;
        int[] tmp, result;
        tmp = new int[myIntA.length + myIntB.length];
        result = new int[myIntA.length + myIntB.length];
        for (int i = 0; i < myIntA.length; i++) 
            for (int j = 0; j < myIntB.length; j++) 
                a = myIntA[i];
                b = myIntB[j];
                s = (a * b);
                tmp[i + j] += s;
            
        
        for (int i = 0; i < tmp.length - 1; i++) 
            c = tmp[i] / 10;
            tmp[i] = tmp[i] % 10;
            tmp[i + 1] = tmp[i + 1] + c;
        
        for (int i = 0; i < tmp.length; i++) 
            result[i] = tmp[i];
        

        while (result[result.length - 1] == 0) 
            tmp = new int[result.length - 1];
            for (int i = 0; i < tmp.length; i++) 
                tmp[i] = result[i];
            
            result = tmp;
        

        MyBigInt r = new MyBigInt("");
        r.setMyInt(result);
        return r;
    

    public void show(int[] i) 
        String s = "";
        int index = i.length - 1;
        for (int j = 0; j < i.length; j++) 
            if (index == i.length - 1 && i[index] == 0) 
                index--;
                continue;
             else 
                s += i[index];
                index--;
            
        
        System.out.println(s);
    

    public String toString() 
        int[] i = getMyInt();
        String s = "";
        int index = i.length - 1;
        if (i.length != 1) 
            for (int j = 0; j < i.length; j++) 
                if (index == i.length - 1 && i[index] == 0) 
                    index--;
                    continue;
                 else 
                    s += i[index];
                    index--;
                
            
         else 
            s += i[index];
        
        return s;
    

    public boolean mod2() 
        boolean flag = false;
        int[] i = myInt;
        if (i[0] % 2 == 0) 
            flag = true;
        
        return flag;
    

    public MyBigInt jiaFa(MyBigInt myBigInt) 
        int[] myIntA = myInt;
        int[] myIntB = myBigInt.getMyInt();
        int[] tmp, result;
        int a;
        if (myIntA.length >= myIntB.length) 
            tmp = new int[myIntA.length + 1];
            for (int i = 0; i < myIntB.length; i++) 
                a = myIntA[i] + myIntB[i] + tmp[i];
                tmp[i] = a % 10;
                tmp[i + 1] = a / 10;
            
            for (int i = myIntB.length; i < myIntA.length; i++) 
                a = tmp[i] + myIntA[i];
                tmp[i] = a % 10;
                tmp[i + 1] = a / 10;
            
         else 
            tmp = new int[myIntB.length + 1];
            for (int i = 0; i < myIntA.length; i++) 
                a = myIntA[i] + myIntB[i] + tmp[i];
                tmp[i] = a % 10;
                tmp[i + 1] = a / 10;
            
            for (int i = myIntA.length; i < myIntB.length; i++) 
                a = tmp[i] + myIntB[i];
                tmp[i] = a % 10;
                tmp[i + 1] = a / 10;
            
        
        result = tmp;

        while (result[result.length - 1] == 0) 
            tmp = new int[result.length - 1];
            for (int i = 0; i < tmp.length; i++) 
                tmp[i] = result[i];
            
            result = tmp;
        

        MyBigInt r = new MyBigInt("");
        r.setMyInt(result);
        return r;
    

    public MyBigInt jianYi() 
        int[] myIntA = myInt;
        myIntA[0] -= 1;
        MyBigInt r = new MyBigInt("");
        r.setMyInt(myIntA);
        return r;
    

    public boolean eqOne() 
        boolean flag = false;
        int[] myIntA = myInt;
        int[] tmp;
        while (myIntA[myIntA.length - 1] == 0) 
            tmp = new int[myIntA.length - 1];
            for (int i = 0; i < tmp.length; i++) 
                tmp[i] = myIntA[i];
            
            myIntA = tmp;
        
        if (myIntA.length == 1 && myIntA[0] == 1) 
            flag = true;
        
        return flag;
    

    public MyBigInt chu2() 
        int[] myIntA = myInt;
        int num;
        int[] tmp, result;
        tmp = new int[myIntA.length];
        for (int i = 0; i < tmp.length; i++) 
            tmp[i] = myIntA[myIntA.length - i - 1];
        
        myIntA = tmp;

        result = new int[myIntA.length];

        for (int i = 0; i < myIntA.length - 1; i++) 
            num = myIntA[i] / 2;
            result[i] = num;
            myIntA[i + 1] += ((myIntA[i] % 2) * 10);
        
        result[result.length - 1] = (myIntA[result.length - 1] / 2);
        tmp = new int[result.length];
        for (int i = 0; i < result.length; i++) 
            tmp[i] = result[result.length - i - 1];
        
        result = tmp;

        while (result[result.length - 1] == 0) 
            tmp = new int[result.length - 1];
            for (int i = 0; i < tmp.length; i++) 
                tmp[i] = result[i];
            
            result = tmp;
        

        MyBigInt r = new MyBigInt("");
        r.setMyInt(result);
        return r;
    

    public MyBigInt jianFa(MyBigInt myBigInt) 
        int[] myIntA = myInt;
        int[] myIntB = myBigInt.getMyInt();
        int[] tmp = new int[myIntA.length];
        int[] result;
        int c = 0;
        for (int i = 0; i < tmp.length; i++) 
            if (myIntA.length == myIntB.length) 
                if (myIntA[i] >= (myIntB[i] + c)) 
                    tmp[i] = myIntA[i] - myIntB[i] - c;
                    c = 0;
                 else 
                    tmp[i] = myIntA[i] + 10 - myIntB[i] - c;
                    c = 1;
                    if (i == tmp.length - 1 && c == 1) 
                        return new MyBigInt();
                    

                

             else if (myIntA.length > myIntB.length) 
                if (myIntB.length - i > 0) 
                    if (myIntA[i] >= (myIntB[i] + c)) 
                        tmp[i] = myIntA[i] - myIntB[i] - c;
                        c = 0;
                     else 
                        tmp[i] = myIntA[i] + 10 - myIntB[i] - c;
                        c = 1;
                    
                 else 
                    if (myIntA[i] - c >= 0) 
                        tmp[i] = myIntA[i] - c;
                        c = 0;
                     else 
                        tmp[i] = myIntA[i] + 10 - c;
                        c = 1;
                    
                
             else if (myIntA.length < myIntB.length) 
                return new MyBigInt();
            
        

        result = tmp;

        while (result[result.length - 1] == 0) 
            if (result.length != 1) 
                tmp = new int[result.length - 1];
                for (int i = 0; i < tmp.length; i++) 
                    tmp[i] = result[i];
                
                result = tmp;
             else 
                return new MyBigInt();
            
        

        MyBigInt r = new MyBigInt("");
        r.setMyInt(result);
        return r;
    

    public MyBigInt youbian(int n) 
        int[] myIntA = myInt;
        int[] result = new int[n / 2];
        for (int i = 0; i < result.length; i++) 
            result[i] = myIntA[i];
        
        MyBigInt r = new MyBigInt("");
        r.setMyInt(result);
        return r;
    

    public MyBigInt zuobian(int n) 
        int[] myIntA = myInt;
        int x;
        int[] result;
        if (n % 2 == 0) 
            x = n / 2;
            result = new int[x];
            for (int i = 0; i < result.length; i++) 
                result[i] = myIntA[x + i];
            
         else 
            x = (n + 1) / 2;
            result = new int[x];
            for (int i = 0; i < result.length; i++) 
                result[i] = myIntA[x + i - 1];
            
        
        MyBigInt r = new MyBigInt("");
        r.setMyInt(result);
        return r;
    

    public MyBigInt cheng2() 
        int[] myIntA = myInt;
        int[] result = new int[myIntA.length + 1];
        int[] tmp;
        for (int i = 0; i < myIntA.length; i++) 
            result[i] += (myIntA[i] * 2) % 10;
            result[i + 1] = (myIntA[i] * 2) / 10;
        

        while (result[result.length - 1] == 0) 
            tmp = new int[result.length - 1];
            for (int i = 0; i < tmp.length; i++) 
                tmp[i] = result[i];
            
            result = tmp;
        
        MyBigInt r = new MyBigInt("");
        r.setMyInt(result);
        return r;
    

参考技术A 1楼的肯定是不对的,既然不能用BigInteger,肯定也不能用类似的BigDecimal。所以一般能想到的方法就是用数组存储高位,像2楼说的竖式乘法一样慢慢算。其实JDK中的BigInteger也是用的这个很基本的算法,只不过它的效率更好,代码更简洁。下面是我写的一个,根据BigInteger的算法改的,效率算是比较优秀了,忘采纳(另外,结果是采用的控制台打印,好像数据大了,控制台会显示不出来,你可以打印到文本当中,这个程序要求栈内存要设置的比较大,不然会内存溢出,加上这个虚拟机参数运行-Xss512m):

public class Factorial

private static final int MAX = 1000000000;
public static final String ENTER = "\n";

public static void main(String args[])

int l = 10000;
int[] result = getFacorial(l);
StringBuilder sb = new StringBuilder();
sb.append(result[result.length - 1]);
for (int i = result.length - 2; i >= 0; i--)

int n = String.valueOf(result[i]).length();
sb.append(("000000000".substring(n) + result[i]));

sb.append(ENTER);
System.out.println("一共" + sb.length() + "位:");
System.out.print(sb.toString());


/**
* 递归算阶乘
* @param L
* @return
*/
public static int[] getFacorial(int n)

if (n == 1) return new int[]1;
int[] multiplyToLen = multiplyToLen(getFacorial(n - 1), n);
return multiplyToLen;


/**
* 主要算法还是跟BigInteger一样,只不过我为了输出,每个int只保留9位。
* @param value
* @param n
* @return
*/
private static int[] multiplyToLen(int[] value, int n)

//n可能大于max,分成两个
long dh = n / MAX;
long dl = n % MAX; //后32位

int xlen = value.length;
//L相当于两个int,可以得出最后的位数最多为 xlen + 2
//可以自己去证明:n位 * m位,结果最多为 n + m位,最少为n + m - 1位
int[] result = (dh == 0L) ? (new int[xlen + 1]) : (new int[xlen + 2]);
long carry = 0;
for (int i = 0; i < xlen; i++)

long product = (value[i]) * dl + carry;
result[i] = (int)(product % MAX);
carry = product / MAX;

result[xlen] = (int)carry;
//算高位
if (dh != 0L)

carry = 0;
for (int i = 0; i < xlen; i++)

long product = (value[i]) * dh + result[i + 1] + carry;
result[i] = (int)(product % MAX);
carry = product / MAX;

result[result.length - 1] = (int)carry;


//carry = 0,证明不需要进最后一位,删除
if (carry == 0L)
result = java.util.Arrays.copyOfRange(result, 0, result.length - 1);
return result;

本回答被提问者和网友采纳
参考技术B 不能用biginteger就用bigdecimal 参考技术C 自己根据乘法的竖式计算方法,逐位计算呗。。。。

。。。况且,百度真能找到现成的

大数的运算--阶乘

今天复习了一下求阶乘

题目:编写一个程序,可以输出10000内的阶乘

#include <cstdio>
#include <cstdlib>
#include <cstring>
#define max_w 8002
#define base 100000

int ans[10002][max_w];
int wei[10002];

int calMulti(int n) {
    int ci = 0;
    for(int i = 0; i < wei[n-1]; i++) {
        int tmp = ans[n-1][i] * n + ci;
        ci = tmp / base;
        ans[n][i] = tmp % base; 
    }
    wei[n] = wei[n-1];
    if(ci != 0) {
        ans[n][wei[n]] = ci;
        wei[n]++;
    }
}

int show(int n) {
    printf("%d",ans[n][wei[n]-1]);
    for(int i = wei[n]-2; i >= 0; i--) {
        printf("%05d",ans[n][i]);
    }

    puts("");
}

int main(int argc, char const *argv[])
{
    memset(ans, 0, sizeof(ans));
    memset(wei, 0, sizeof(wei));
    ans[0][0] = 1;
    ans[1][0] = 1;
    wei[0] = wei[1] = 1;
    for(int i = 2; i <= 10000; i++) {
        calMulti(i);
    }
    int n;
    while(scanf("%d",&n) != EOF) {
        show(n);
        printf("%d\n",wei[10000]);
    }
    return 0;
}

 

因为int的范围大致是9位,所以base的最大值是 1000000000/10000 = 100000,超过这个值就可能发生溢出的现象

10000的阶乘大致有4 * 10000 = 40000位,10000的阶乘不超过40000/5 = 8000位(事实上,有7132位)

以上是关于求编个java程序要求:编写一个求大数的阶乘,不能用biginteger,并且使用数组不能浪费,不的主要内容,如果未能解决你的问题,请参考以下文章

大数的运算--阶乘

hdu1042 N!(大数求阶乘)

按要求编写Java程序(阶乘)

分治法求x的n次方的JAVA程序

求大神帮忙用JAVA编个程序,定义抽象类Function,其中包含抽象方法doFunction()。

2、设计一个shell程序计算n的阶乘。要求:(15分) (1) 从命令行接收参数n; (2) 在程序开始后立即判断n的合