用栈实现两个大数相加
问题分析:整数是有最大上限的,所谓大数是超过整数最大上限的数,无法用整型来保存;
为把两个大数相加,可以把两个加数看成字符串,将这些数的相应数字储存在两个堆栈中,并将两个栈中弹出对应为的数字依次相加
算法归纳:
1。将两个加数的相应位从高位到低位写入栈中
2.依次弹出两个加数的栈顶(最低位)相加;
若有进位,则将和的个位存入栈sum中,并将进位加到下一位的和中,若没有进位,则直接加入栈sum中
3.若其中一个栈为空,则将非空栈的栈顶数字依次弹出与进位相加,和的个位压入栈sum中,直到栈为空为止
若最高位有进位,则将1压入栈sum中
4若两个栈都为空,则sun栈中保存为计算结果,注意栈顶是结果中最高位的数字
import java.util.Stack;
public class Example3_2 {
//求两个大数的和,加数以字符串的形式输入,(允许出现字符),计算结果也是字符串返回
public String add(String a,String b) throws Exception{
Stack sum=new Stack();
Stack sA=numSplit(a);
Stack sB=numSplit(b);
int partialSum; //对于两个位的求和
boolean isCarry=false; //进位的标志
while(!sA.isEmpty()&&!sB.isEmpty()){
//将A,B取出栈顶(即最低位)相加
partialSum=(Integer)sA.pop()+(Integer)sB.pop();
if(isCarry){
//如果需要进位,则加一,并将进位标志置false
partialSum++;
isCarry=false;
}
if(partialSum>=10){
//若partialSum大于10,则减去10并将进位标志置true,最后压入栈中
isCarry=true;
partialSum-=10;
sum.push(partialSum);
}else{
sum.push(partialSum);
}
}
//若sA栈或者sB栈有一个为空或者两个都为空
Stack temp=!sA.isEmpty()?sA:sB;//指向非空栈
while(!temp.isEmpty()) {
if(isCarry){
int t=(Integer)temp.pop();
++t;
if(t>=10){
t-=10;
sum.push(t);
}
else {
sum.push(t);
isCarry=false;}
}
sum.push(temp.pop());
}
if(isCarry){
sum.push(1);//若最高位需要进位,则进位
}
String str =new String();
while(!sum.isEmpty()){
//把栈中元素转换成字符串
str=str.concat(sum.pop().toString());
}return str;
}
//将字符串从高位至低位依次写入栈中,并且去除字符串的空格,返回以单个字符作为元素的栈
public Stack numSplit(String str) throws Exception{
Stack s=new Stack<>();
for(int i=0;i
char c=str.charAt(i);
//去除空格
if(c==' '){
continue;}
else if(c>='0'&&c<='9'){
//数字放入栈中
s.push(Integer.valueOf(str.valueOf(c)));
}else{
//非法数字
throw new Exception("错误:输入了非数字性的字符");
}
}
return s;
}
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
Example3_2 e=new Example3_2();
System.out.println("两个大数的和为:"+e.add("18 452 543 389 945 209 752 345 473", "8 123 542 678 432 986 899 334 "));
}
}
运行结果如下:
两个大数的和为:18460666932623642739244807