很多公司面试都会有一个问题,就是求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 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;
}
}