昨天去参加某个公司的面试,前面的聊天还是挺愉快的,最后他给我出了道题,叫我算1000的阶乘。首先的想法是递归或者循环计算,但是思考了一下1000的阶乘的结果int和long肯定是存不下的,改用BigInteger别人不允许,最后就结果可想而知---被深深地鄙视了。我肯定是吞不下这口气啊,五分钟不够你就让我写出来,还是只有笔和纸。回到小窝,怀着郁闷和悲愤的心情,坚决攻克。最后就有如下的成果了。
测试结果:
1000的阶乘139ms,结果长度为2568;
10000的阶乘21909ms,结果程度为35660
代码如下:
/**
* 计算从Start到end的乘积
*
* @param start
* 开始索引
* @param end
* 结束索引
* @return 结果的字符串
*/
private static String getNumber(int start, int end) {
String str = Integer.toString(start);
for (int i = start; i < end; i++) {
str = getBigInteger(str, Integer.toString(i + 1));
}
return str;
}
// 计算两个数的乘积,任何长度
private static String getBigInteger(String str1, String str2) {
// 字符串长度
int len1 = str1.length();
int len2 = str2.length();
// 存储最先添加的尾数
StringBuffer buffer = new StringBuffer();
// 存储最后一次加法运算的结果
StringBuffer b = new StringBuffer();
// 存储每一位相乘的结果
int[] result = new int[len1 + 1];
// 将字符串转换为整型数组
char[] temp1 = str1.toCharArray();
char[] temp2 = str2.toCharArray();
int[] num1 = new int[len1];
int[] num2 = new int[len2];
// 初始化数组
for (int i = 0; i < len1; i++) {
num1[i] = Character.getNumericValue(temp1[i]);
}
// System.out.println();
for (int j = 0; j < len2; j++) {
num2[j] = Character.getNumericValue(temp2[j]);
}
// 计算每一位相乘的结果
for (int i = len2 - 1; i >= 0; i--) {
// 进位
int carry = 0;
// 从最低位算起
for (int j = len1 - 1; j >= 0; j--) {
// 加上进位和上一次运算结果的第j位得到该位的值
int res = num2[i] * num1[j] + carry + result[j];
carry = 0;
// 如果结果大于等于10,得到进位值
if (res >= 10) {
carry = res / 10;
}
// 得到该位的结果
result[j + 1] = res % 10;
if (i <= 0 && j < len1 - 1) {
b.append(result[j + 1]);
}
}
// 最高位为进位值
result[0] = carry;
// 添加结果的最后一位
buffer.append(result[len1]);
if (i <= 0) {
// 添加最高位
b.append(result[0]);
buffer.append(b);
}
}
return reverseStringAndClearZero(buffer.toString());
}
// 反向输出结果并且去掉最前面的0
private static String reverseStringAndClearZero(String str) {
StringBuffer buffer = new StringBuffer();
boolean isZero = true;
for (int i = str.length() - 1; i >= 0; i--) {
if (isZero && str.charAt(i) != '0') {
isZero = false;
}
if (!isZero) {
buffer.append(str.charAt(i));
}
}
return buffer.toString();
}
小子不才,速度只能这样了,如果哪位大侠有更好的解决方案,请告知,谢谢