*文中内容来源于《数据结构 --Java语言描述》(第二版) 刘小晶 杜选 主编
*此系列文章作为学习记录,若文中内容有误,请大家指出,谢谢
整数是有最大上限的。所谓大数就是超过整数最大上限的数。为解决两个大数的求和问题,可以将两个大数当成数字字符串,将这些数的相应数字存储在两个堆栈中,并从两个栈中弹出相应位的数字依次执行加法即可求解。
//求两个大数的和,加数和被加数以字符串的形式输入(允许大数中出现空格)
//计算的结果也以字符串的形式返回
/**
* 对于两个大数的加法,操作步骤如下:
* (1)将两个加数的相应位从高位到低位依次压入栈sA和sB中;
* (2)若两个加数栈都非空,则依次从栈中弹出栈顶数字相加,并存入变量partialSum中;
* 若和有进位,则将和的个数压入结果栈sum中,并将进位数加到下一位数字相加的和中;
* 若和没有进位,则直接将和压入结果栈sum中;
* (3)若某个加数堆栈为空,则将非空加数栈中的栈顶数字依次弹出与进位相加,
* 和的个数压入结果栈sum中,直到此栈为空为止。若最高位有进位,则最后将1压入栈sum中;
* (4)若两个加数栈都为空,则栈sum中保存的就是计算结果。注意栈顶是结果的最高为数字。
*/
public class Example3_2 {
public String add(String a, String b) throws Exception{
LinkStack sum = new LinkStack(); //大数的和
LinkStack sA = numSplit(a); //加数字符串以单个字符的形式放入栈中
LinkStack sB = numSplit(b); //被加数字符串以单个字符的形式放入栈中
int partialSum; //对于两个位的求和
boolean isCarry = false; //进位标示
while(! sA.isEmpty() && !sB.isEmpty()){ //加数和被加数栈同时为空
partialSum = (Integer)sA.pop() + (Integer)sB.pop(); //对于两个位求和,并在栈中去除加数和被加数中的该位
if (isCarry){ //低位进位
partialSum++; //进位加到此位上
isCarry = false; //重置进位标示
}
if (partialSum >= 10){ //需要进位
partialSum -= 10;
sum.push(partialSum);
isCarry = true; //标示进位
}
else { //位和不需要进位
sum.push(partialSum); //和放入栈中
}
}
LinkStack 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; //重置进位标示
}
}
else //最后一次执行加法运算中不需要进位
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 LinkStack numSplit(String str) throws Exception{
LinkStack s = new LinkStack();
for (int i = 0; i < str.length(); i++){
char c = str.charAt(i); //指定索引处的char值
if (' ' == c)
continue;
else if ('0' <= c && '9' >= c) //数字放在栈中
s.push(Integer.valueOf(String.valueOf(c)));
else
throw new Exception("错误:输入了非数字型字符!");
}
return s;
}
public static void main(String[] args) throws Exception{
Example3_2 e = new Example3_2();
System.out.println("两个大数的和为:" + e.add("18 452 543 389 943 209 752 345 473", "8 123 542 678 432 986 899 334"));
}
}
关于顺序栈的相关代码,都在 栈 这篇文章里了。