Java链栈实现两个大数加法

来源:互联网 发布:天下3捏脸大赛数据 编辑:程序博客网 时间:2024/05/16 16:56

整数是有上限的,所谓大数,是指超过整数最大上限的数,例如18452545389943209751345473,

它是无法用整数变量来保存的。为解决两个大数求和问题,可以把两个加数看成是数字字符串


由于最先写的高位反而最后运算,满足栈先进后出的特性,因此选择用栈来解决这个问题。


操作步骤如下:

1)将两个加数的相应位从高位到低位依次压入栈sA和sB中。

2)若两个加数栈都非空,则依次从栈中弹出栈顶数字相加,和存入变量partialSum中;

若和有进位,则将和的个位数压入结果栈sum中,并将进位数加到下一位数字相加的和中;

若没有进位,则直接将和压入结果栈sum中。

3)若某个加数堆栈为空,则将非空加数的栈顶数字依次弹出与进位相加,和的个位数压入结果栈sum中,

直到该栈为空为止,若最高位有进位,则最后将1压入sum中。

4)若两个加数栈都为空,则栈sum中保存的就是计算结果。此时栈顶存储的是最高位数字。


代码如下,用到了之前实现的链栈,代码中有详细注释

package com.stack;public class AdditionOfLargeNumbers {public static 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 && c <= '9') {s.push(Integer.valueOf(String.valueOf(c)));} else {throw new Exception("错误:输入了非数字类型");}}return s;}public static String add(String oa, String ob) throws Exception {LinkStack sum = new LinkStack();LinkStack sA = numSplit(oa);LinkStack sB = numSplit(ob);int partialSum = 0;// 存储单位数字相加的结果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()?sB:sA;//如果sA为空则加sB,否则sB为空加sAwhile(!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 static void main(String[] args) throws Exception {System.out.println(add("18 452 543 389 943 209 752 345 473","8 123 542 678 432 986 899 334"));}}




0 0
原创粉丝点击