数据结构Java实现——①栈-->栈的应用一、大数相加

这篇博客探讨了如何使用数据结构中的栈来解决大数相加的问题。通过详细阐述问题描述、解决思路,并提供了两种代码实现方式,包括自定义栈和利用Java类库中的栈,旨在深化对栈的理解并拓展解题思维。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

写在前面


只是学栈的描述之类的似乎很无聊,所以我特意找了几个比较有意思的例子,一则加深对栈的理解和运用,二则,也可以开拓一下思路,此处为例一


例一、大数相加


1、问题描述


如题,两个比较大的数(几百位)相加,如何才能处理????

2、思路


(1)将两个加数的相对应位从高位到低位依次压入栈,SA和SB
(2)若两个栈都非空,则依次从栈中弹出栈顶数字相加,将结果的个位数添加到结果栈Sum中,结果的十位数与下次的和相加
(3)若某个加数栈为空,则将非空栈的栈顶元素弹出与进位数相加,结果的个位数放到Sum中,若最高位有进位, 则最后将1压入栈
(4)若两个栈均为空,则结果栈中保存的就是最后的结果,注意栈顶是结果中的最高位

3、代码实现


(1)用自己定义的栈实现

package org.Stone6762.MStack.adopt;

import java.util.Scanner;

import org.Stone6762.MStack.imple.LinkStack;

/**
 * @author_Stone6762
 * @Description_大数相加
 * */
public class BigAdd {

	/**
	 * @Describe_将表示数字的字符串从高位到低位的形式压入栈_并去除其中的空格
	 * @param str
	 * @return
	 * @throws Exception
	 */
	public LinkStack numSplit(String str) throws Exception {
		LinkStack s = new LinkStack();
		for (int i = 0; i < str.length(); i++) {
			char c = str.charAt(i);
			if (' ' == c) {
				continue;
			}
			if (c >= '0' && c <= '9') {
				s.push(c + "");
			} else {
				throw new Exception("错误: 输入了非数字类型的字符!  ");
			}
		}
		return s;
	}

	/**
	 * @Describe_求两个大数的和_加数和被加数以字符串的形式给出_计算的结果也以字符串的形式返回
	 * @param a
	 * @param b
	 * @return
	 * @throws Exception
	 */
	public String add(String a, String b) throws Exception {
		LinkStack sum = new LinkStack();
		LinkStack sA = numSplit(a);
		LinkStack sB = numSplit(b);
		int tSum;// 表示两位的和
		boolean isCarry = false;// 是否有进位
		// 当两个栈都非空时,依次出栈,然后相加
		while (!sA.isEmpty() && !sB.isEmpty()) {
			tSum = Integer.valueOf((String) sA.pop())
					+ Integer.valueOf((String) sB.pop());
			if (isCarry) {
				tSum++;
				isCarry = false;// 将低位的进位状态消除掉,防止影响下次的使用
			}
			if (tSum >= 10) {
				tSum -= 10;
				isCarry = true;
			}
			sum.push(tSum);
		}
		LinkStack temp = !sA.isEmpty() ? sA : sB;

		// 当其中一个为空时,对另一个非空的进行操作
		while (!temp.isEmpty()) {
			int t = Integer.valueOf((String) temp.pop());
			if (isCarry) {// 第一个isCarry为上面的残留
				t++;
				if (t >= 10) {
					t -= 10;
				} else {
					isCarry = false;// 只有当上一次是true,且这一次没有进位时,才需要对isCarry进行修改
				}
			}
			sum.push(t);
		}
		// 对最后一次相加的十位的数字进行判断
		if (isCarry) {
			sum.push(1);
		}
		return stack2Str(sum);
	}

	/**
	 * @Describe_将一个栈中的数据从栈顶到栈底变成一个字符串
	 * @param sum
	 * @return
	 */
	public String stack2Str(LinkStack s) {
		String str = "";
		while (!s.isEmpty()) {
			str += s.pop().toString();
		}
		return str;
	}

	public static void main(String[] args) throws Exception {
		BigAdd s = new BigAdd();
		Scanner scan = new Scanner(System.in);
		while (scan.hasNext()) {
			String a = scan.next();
			String b = scan.next();
			System.out.println(s.add(a, b));
		}
	}

}



(2)用java类库中给点栈实现



import java.util.Stack;

/**
 * @ClassName_BigAdd大数相加
 * @author_Stone6762
 * @CreationTime_2016年10月22日17:36:45
 * @Description_算法描述
 * */
/*
 * 算法描述 (1)将两个加数的相对应位从高位到低位依次压入栈,SA和SB
 * (2)若两个栈都非空,则依次从栈中弹出栈顶数字相加,将结果的个位数添加到结果栈Sum中,结果的十位数与下次的和相加
 * (3)若某个加数栈为空,则将非空栈的栈顶元素弹出与进位数相加,结果的个位数放到Sum中,若最高位有进位, 则最后将1压入栈
 * (4)若两个栈均为空,则结果栈中保存的就是最后的结果,注意栈顶是结果中的最高位
 */
public class MyBigAdd {

	

	/**
	 * @Describe_将表示数字的字符串从高位到低位的形式压入栈_并去除其中的空格
	 * @param str
	 * @return
	 * @throws Exception
	 */
	private static Stack<String> numSplit(String str) throws Exception {

		Stack<String> s = new Stack<String>();
		for (int i = 0; i < str.length(); i++) {
			char c = str.charAt(i);
			if (' ' == c) {
				continue;
			}
			if (c >= '0' && c <= '9') {
				s.push(c + "");
			} else {
				throw new Exception("错误: 输入了非数字类型的字符!  ");
			}
		}
		return s;
	}

	/**
	 * @Describe_求两个大数的和_加数和被加数以字符串的形式给出_计算的结果也以字符串的形式返回
	 * @param a
	 * @param b
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("finally")
	public static String add(String a, String b) {
		Stack<String> sum = new Stack<String>();
		try {
			Stack<String> sA = numSplit(a);
			Stack<String> sB = numSplit(b);

			int tSum;// 表示两位的和
			boolean isCarry = false;// 是否有进位
			// 当两个栈都非空时,依次出栈,然后相加
			while (!sA.isEmpty() && !sB.isEmpty()) {
				tSum = Integer.valueOf((String) sA.pop())
						+ Integer.valueOf((String) sB.pop());
				if (isCarry) {
					tSum++;
					isCarry = false;// 将低位的进位状态消除掉,防止影响下次的使用
				}
				if (tSum >= 10) {
					tSum -= 10;
					isCarry = true;
				}
				sum.push("" + tSum);
			}
			Stack<String> temp = !sA.isEmpty() ? sA : sB;

			// 当其中一个为空时,对另一个非空的进行操作
			while (!temp.isEmpty()) {
				int t = Integer.valueOf((String) temp.pop());
				if (isCarry) {// 第一个isCarry为上面的残留
					t++;
					if (t >= 10) {
						t -= 10;
					} else {
						isCarry = false;// 只有当上一次是true,且这一次没有进位时,才需要对isCarry进行修改
					}
				}
				sum.push("" + t);
			}
			// 对最后一次相加的十位的数字进行判断
			if (isCarry) {
				sum.push("" + 1);
			}
			

		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			return stack2Str(sum);
		}

	}

	/**
	 * @Describe_将一个栈中的数据从栈顶到栈底变成一个字符串
	 * @param sum
	 * @return
	 */
	private static String stack2Str(Stack<String> s) {
		String str = "";
		while (!s.isEmpty()) {
			str += s.pop().toString();
		}
		return str;
	}

}







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值