求1到1000阶乘之和
今天在脉脉的匿名区看到一个这个面试题,有个面试官说面试者连这道题都不会写,我想了几分钟就能解出来,把代码写下来。写得有点繁琐了~~~,有高手可以指导更简单的方法了么。。。
求一个简单的阶乘很简单,难的是当到后面结算的结果超过int 或者超过bigint的范围的时候 ,数值就会错误。
核心的思想就是把简单的阶乘和变成大数的加法和乘法
import java.util.LinkedList;
import java.util.Queue;
public class BigNumerber {
/**
* @param args
* @author xiaoyizong@126.com
* @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;
}
}