所谓大数是指超过整数最大上限的数,是无法用一般的int整型变量来保存的,因此也不能通过直接的加法运算来求得它们的和。
要解决这个问题,可以把两个加数看成字符串,将字符串中的相应数字分别存入两个栈中,每次从两个栈弹出对应位的数字相加,和(或和的个位数)存入结果栈中。
简要步骤:
- 将两个加法的相应位从高位到低位依次压入栈stackA和stackB中,结果栈stackSum用来存放最终和
- 如果两个栈非空,则依次从栈中弹出栈顶数字相加,和存入临时变量tempSum中。若和有进位,则将个位数压入结果压入结果栈。stackSum,并标志进位isCarry为true,以便将进位数加入到下次数字和中;若无进位,则直接将和压入结果栈stackSum
- 步骤2后如果有栈非空(即两个加数位数不同),则依次弹出非空栈stackTemp的栈顶数字。若有进位则与进位数相加,将和个位数压栈;若无则直接压栈
- 如果最高位有进位,则最后将数字1入栈
- 打印结果栈stackSum中数字,得到结果和
代码如下:
public class LargeCalculate {
//把字符串以字符形式放进栈中
public Stack stringToStack(String str)
{
Stack stack=new Stack();
for(int i=0; i<str.length(); i++)
{
char c=str.charAt(i);
if(c>='0' && c<='9')
stack.push(Integer.valueOf(String.valueOf(c)));
else
continue;
}
return stack;
}
//大数相加
public String add(String a, String b)
{
Stack stackA=stringToStack(a); //存放第一个数
Stack stackB=stringToStack(b); //存放第二个数
Stack stackSum=new Stack(); //存放结果和
int tempSum; //两位数求和
boolean isCarry=false; //进位标志
while(!stackA.isEmpty() && !stackB.isEmpty())
{
tempSum=(Integer)stackA.pop()+(Integer)stackB.pop();
//若有进位,加1
if(isCarry)
{
tempSum++;
isCarry=false;
}
//位数和大于10,个位数入栈,标志进位
if(tempSum>=10)
{
tempSum-=10;
stackSum.push(tempSum);
isCarry=true;
}
else
{
stackSum.push(tempSum);
}
}
//取不为空的栈
Stack stackTemp=!stackA.isEmpty()?stackA:stackB;
while(!stackTemp.isEmpty())
{
//若原先有进位
if(isCarry)
{
int end= (Integer)stackTemp.pop(); //取出栈中的数
++end;
if(end>=10) //大于10,进位
{
end-=10;
stackSum.push(end);
}
else //小于10,直接入栈
{
stackSum.push(end);
isCarry=false;
}
}
//若原先无进位
else
{
stackSum.push(stackTemp.pop());
}
}
//最高位有进位时,直接最后一个数为1
if(isCarry)
stackSum.push(1);
//把栈中结果转为字符串
String result=new String();
while(!stackSum.isEmpty())
{
result=result.concat(stackSum.pop().toString());
}
return result;
}
public static void main(String[] args) {
LargeCalculate largeCalculate=new LargeCalculate();
String a="6 293 379 654 943 111 722 643 403";
String b="1 523 502 388 432 201 489 337 789";
System.out.println("和为: "+largeCalculate.add(a,b));
}
}
运行结果:
看时难,做时易,花点小时间就能搞定的。大数减法运算思想类似。如有错误,欢迎指正!(凡星逝水2017)