程序求1!+2!+3!+...+1000!的和, 求1到1000階乘之和

求1到1000階乘之和

今天在脈脈的匿名區看到一個這個面試題,有個面試官說面試者連這道題都不會寫,我想了幾分鐘就能解出來,把代碼寫下來。寫得有點繁瑣了~~~,有高手可以指導更簡單的方法了麼。。。

求一個簡單的階乘很簡單,難的是當到後面結算的結果超過int 或者超過bigint的範圍的時候 ,數值就會錯誤。

核心的思想就是把簡單的階乘和變成大數的加法和乘法

import java.util.LinkedList;
import java.util.Queue;
public class BigNumerber {
    /**
     * @param args
     * @author [email protected]
     * @time 20160603 22:17
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        //求1!+2!+3!+....+1000!
        //求1到1000階乘之和,解法很簡單,就是把小數的乘法和加法變成大數的加法和乘法
        String a="1";
        String s="0";
        for(int i=1;i<=1000;i++)
        {
            a=bigNumberMultiply(a,String.valueOf(i)); 
            s=bigNumberAdd(s,a);
        }
        System.out.println(s);
    }

    public static String bigNumberAdd(String addend,String augend){
        //大數的加法很簡單,多一個進位就行了,因爲最大的數是9+9=18,
        int carry = 0;//進位
        int len_add = 0;
        int len_agd = 0;
        int bigcount = 0;
        int smallcount = 0;
        int r,d,sum = 0;
        final String number = "0123456789";
        StringBuffer s_buf = new StringBuffer();
        String longstr = null;
        String s = null;
        if(addend != null && augend != null){
            len_add = addend.length();
            len_agd = augend.length();
            bigcount = len_add > len_agd ? len_add : len_agd;
            smallcount = len_add < len_agd ? len_add : len_agd;
            longstr = len_add > len_agd ? addend: augend;

        }else{
            return "-1";
        }
        for(int i = 0 ;i<bigcount ;i++){
            if(i < smallcount){
                if((number.indexOf(addend.charAt(len_add - i -1)) != -1 )&&(number.indexOf(augend.charAt(len_agd -i -1)) != -1)){
                     r = Integer.parseInt(String.valueOf(addend.charAt(len_add - i -1)));
                     d = Integer.parseInt(String.valueOf(augend.charAt(len_agd - i -1)));
                     sum = r + d + carry;//計算對應位數的值加之後的和
                     if (sum >= 10){//如果和大於等於10進一位
                         s = String.valueOf(sum);
                         carry = Integer.valueOf(s.substring(0, 1));
                         sum = Integer.valueOf(s.substring(1, 2));
                     }else{
                         carry = 0; 
                     }
                }else{
                    return "-1";
                }
            }else if(number.indexOf(longstr.charAt(bigcount - i -1)) != -1 ){
                sum = Integer.parseInt(String.valueOf(longstr.charAt(bigcount - i -1))) + carry;
                if (sum >= 10){
                     s = String.valueOf(sum);
                     carry = Integer.valueOf(s.substring(0, 1));
                     sum = Integer.valueOf(s.substring(1, 2));
                 }else{
                     carry = 0; 
                 }
            }

            s_buf.append(sum);
        }
        if(carry > 0){
            s_buf.append(carry);
            carry=0;
        }
        return s_buf.reverse().toString();
    }

    public static String bigNumberMultiply(String multiplier ,String multiplicand){
        //大數的乘法一樣,將每一位數字與另外一個個數相乘,再相加之後得到結果
        Queue<String> queue = new LinkedList<String>();
        int len_mpr,len_mpd,bigcount,smallcount,sum,last,d=0;
        int carry = 0;
        String s = null;
        String longstr,shortstr= null;
        final String number = "0123456789";
        StringBuffer s_buf = new StringBuffer();
        if(multiplier != null && multiplicand != null){
            len_mpr = multiplier.length();
            len_mpd = multiplicand.length();
            bigcount = len_mpr > len_mpd ? len_mpr : len_mpd;
            smallcount =len_mpr < len_mpd ? len_mpr : len_mpd;
            longstr = len_mpr > len_mpd ? multiplier: multiplicand;
            shortstr = longstr.equals(multiplicand)?multiplier:multiplicand;

        }else{
            return "-1";
        }
        for(int i=0;i < smallcount ;i++){
            //將每個數進位與另外一個數相乘,放到一個鏈表裏面存在
            if (number.indexOf(shortstr.charAt(smallcount - i - 1)) != -1) {
                last = Integer.parseInt(String.valueOf(shortstr.charAt(smallcount - i - 1)));
                for (int j = 0; j < bigcount; j++) {
                    if (Integer.parseInt(String.valueOf(longstr.charAt(bigcount- j - 1))) != -1) {
                        d = Integer.parseInt(String.valueOf(longstr.charAt(bigcount - j - 1)));
                        sum = last * d + carry;
                        if (sum >= 10) {
                            s = String.valueOf(sum);
                            carry = Integer.valueOf(s.substring(0, 1));
                            sum = Integer.valueOf(s.substring(1, 2));
                        } else {
                            carry = 0;
                        }

                        s_buf.append(sum);
                    } else {
                        return "-1";
                    }
                }//j++
                if(carry >0){
                    s_buf.append(carry);
                    carry = 0;
                }
                queue.offer(s_buf.reverse().toString());
                s_buf.delete(0, s_buf.length());
            }else{
                return "-1";
            }
        }//i++
        String res = "0";
        int size = queue.size();
        for(int k =queue.size();k > 0; k--){
            //高位需要補0
            StringBuffer num  = new StringBuffer(queue.poll());
            for(int l = 0;l<size -k;l++){
                num.append("0");
            }
            res = bigNumberAdd(res,num.toString()); 
        }
        return res;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章