栈解决大数加法问题(Java实现)

*文中内容来源于《数据结构 --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"));
    }
}

关于顺序栈的相关代码,都在 这篇文章里了。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值