用栈实现简易计算器(只用于整数)

这篇博客介绍了如何使用Java实现逆波兰表达式的计算,以及从中缀表达式转换为后缀表达式的方法。通过两个栈来处理运算符和数字,详细解释了中缀转后缀的步骤,并给出了具体的代码实现,包括遇到括号和不同运算符时的处理策略。此外,还展示了如何根据后缀表达式进行计算,最终得出结果。
摘要由CSDN通过智能技术生成

这个比较简单,但是由于Java基础太差,一些地方只能跟着课程写,自己不会写,记一下代码吧,Java要坚持学习

有几点需要解决的问题:

用字符串表示逆波兰式时,为了方便直接用空格把各项隔开了,如果不这样的话还能怎么实现,以及尤其是多位数的话,还有什么方法

其次,对于泛型的使用、ArrayList类和List接口的使用:

List<String> list = new ArrayList<String>();// 泛型

在进行计算的时候,给num1和Num2赋值,要注意出栈和计算对应的顺序


	// 把表达式存到ArrayList中
	public static List<String> getListString(String backexpresion) {
		String[] split = backexpresion.split(" ");
		// ArrayList动态修改的数组,没有固定大小限制
		// 遍历ArrayList存入栈
		List<String> list = new ArrayList<String>();// 泛型
		for (String ele : split) {
			list.add(ele);
		}
		return list;
	}

	public static int calcluator(List<String> list) {
		int res = 0;
		int num1 = 0;
		int num2 = 0;
		Stack<String> stack = new Stack<String>();
		for (String item : list) {
			if (item.matches("\\d+")) {// 匹配的是多位数("+")
				// 是数字
				stack.push(item);
			} else {
				// 不是数字
				// 这里要注意Num1和num2的顺序
				num2 = Integer.parseInt(stack.pop());
				num1 = Integer.parseInt(stack.pop());

				if (item.equals("*")) {
					res = num1 * num2;
					stack.push(res + "");
				} else if (item.equals("/")) {
					res = num1 / num2;
					stack.push(res + "");
				} else if (item.equals("+")) {
					res = num1 + num2;
					stack.push(res + "");
				} else if (item.equals("-")) {
					res = num1 - num2;
					stack.push(res + "");
				} else {
					// 不是四则运算的运算符
					throw new RuntimeException("运算符不合法");
				}
			}
		}
		return res;
	}

更新:

使用中缀表达式转换成后缀表达式来进行计算:

以下是中缀转后缀:

思路:
 需要2个栈,s1只能存储运算符和括号(认为括号不属于运算符),s2存储中间结果(存储数和运算符)
 从左往右遍历中缀表达式,遇到数,s2.push()
 遇到运算符,有几种情况:1.s1为空或者s1.peek()为左括号,直接入栈;2.优先级大于s1.peek(),直接入栈;3.else,s1栈顶出栈并入s2中,重复这个过程
遇到的符号是括号,有2种情况:1.是(,直接入栈;2.是),把s1的栈顶出栈并入s2中,重复一直到s1.peek()="(",把这一对括号抵消掉(不要这对括号了)
 重复以上步骤,直到遍历结束,此时s1依次出栈并入s2,最终,s1为空,s2从栈底-->栈顶的顺序元素就是要求的后缀表达式

PS:由于s2中途只有入栈操作,且最后需要进行逆序,所以可以直接用一个ArrayList来代替

这是中缀转后缀的方法:

//中缀表达式转后缀表达式
/*思路:
 * 需要2个栈,s1只能存储运算符和括号(认为括号不属于运算符),s2存储中间结果(存储数和运算符)
 * 从左往右遍历中缀表达式,遇到数,s2.push()
 * 遇到运算符,有几种情况:1.s1为空或者s1.peek()为左括号,直接入栈;2.优先级大于s1.peek(),直接入栈;3.else,s1栈顶出栈并入s2中,重复这个过程
 * 遇到的符号是括号,有2种情况:1.是(,直接入栈;2.是),把s1的栈顶出栈并入s2中,重复一直到s1.peek()="(",把这一对括号抵消掉(不要这对括号了)
 * 重复以上步骤,直到遍历结束,此时s1依次出栈并入s2,最终,s1为空,s2从栈底——》栈顶的顺序元素就是要求的后缀表达式
 */

	public static List<String> exchange(List<String> list) {
		// String resSufix = "";// 得到的后缀表达式
		Stack<String> stack1 = new Stack<String>();
		// Stack<String> stack2 = new Stack<String>();
		// 说明:stack2这个栈中途没有出栈操作而且最后需要逆序操作,所以可以直接用一个ArrayList替代
		List<String> stacklist = new ArrayList<String>();

		for (String item : list) {
			// 对item进行判断
			if (item.matches("\\d+")) {// 是数字
				// stack2.push(item);
				stacklist.add(item);
			} else {// 是符号,按照运算符和括号分别讨论
				switch (item) {
				case "+":
					if (stack1.empty() || stack1.peek() == "(") {
						stack1.push(item);
						break;
					} else if (perioity(item) > perioity(stack1.peek()) && stack1.peek() != "(") {
						stack1.push(item);
						break;
					} else {
						while (true) {
							// stack2.push(stack1.pop());
							stacklist.add(stack1.pop());
							if (stack1.empty() || stack1.peek() == "(" || perioity(item) > perioity(stack1.peek())) {
								stack1.push(item);
								break;
							}
						}
					}

					break;
				case "-":
					if (stack1.empty() || stack1.peek() == "(") {
						stack1.push(item);
						break;
					} else if (perioity(item) > perioity(stack1.peek()) && stack1.peek() != "(") {
						stack1.push(item);
						break;
					} else {
						while (true) {
							// stack2.push(stack1.pop());
							stacklist.add(stack1.pop());
							if (stack1.empty() || stack1.peek() == "(" || perioity(item) > perioity(stack1.peek())) {
								stack1.push(item);
								break;
							}
						}
					}
					break;
				case "*":
					if (stack1.empty() || stack1.peek() == "(") {
						stack1.push(item);
						break;
					} else if (perioity(item) > perioity(stack1.peek()) && stack1.peek() != "(") {
						stack1.push(item);
						break;
					} else {
						while (true) {
							// stack2.push(stack1.pop());
							stacklist.add(stack1.pop());
							if (stack1.empty() || stack1.peek() == "(" || perioity(item) > perioity(stack1.peek())) {
								stack1.push(item);
								break;
							}
						}
					}
					break;
				case "/":
					if (stack1.empty() || stack1.peek() == "(") {
						stack1.push(item);
						break;
					} else if (perioity(item) > perioity(stack1.peek()) && stack1.peek() != "(") {
						stack1.push(item);
						break;
					} else {
						while (true) {
							// stack2.push(stack1.pop());
							stacklist.add(stack1.pop());
							if (stack1.empty() || stack1.peek() == "(" || perioity(item) > perioity(stack1.peek())) {
								stack1.push(item);
								break;
							}
						}
					}
					break;
				case "(":
					stack1.push(item);
					break;
				case ")":// 这里消除括号有问题
					//问题出现在:我写的是stack1.peek()!="("改成用equals()后不再报错
					while (!stack1.peek().equals("(")) {// 这一行报错,提示栈空的异常:EmptyStackException
						// stack2.push(stack1.pop());
						stacklist.add(stack1.pop());
					}
					//新的问题,(没有出栈,结果输出显示有两个(,问题出现在这个if上
					/*if (stack1.peek().equals("(")) {
						stack1.pop();
						break;
					}*/
					stack1.pop();
					break;
				default:
					System.out.println("运算符不合法");
					break;
				}
			}
		} // 入栈结束,开始出栈
		while (!stack1.empty()) {
			// stack2.push(stack1.pop());
			stacklist.add(stack1.pop());
		}
		
		return stacklist;
	}

这是计算的方法:

public static int calculator(List<String> ls) {
		// 进行计算
		int num1 = 0, num2 = 0;
		int res = 0;
		Stack<String> stack = new Stack();
		// 对List的数据进行判断,如果是数就存到栈中,如果是运算符就取出栈顶和次顶数据进行计算,计算结果存到栈中,然后继续判断List数据
		for (String item : ls) {// 遍历ls
			if (item.matches("\\d+")) {
				stack.push(item);
			} else {
				num1 = Integer.parseInt(stack.pop());
				num2 = Integer.parseInt(stack.pop());
				if (item.equals("+")) {
					res = num2 + num1;
					stack.push(res + "");
				} else if (item.equals("-")) {
					res = num2 - num1;
					stack.push(res + "");
				} else if (item.equals("*")) {
					res = num2 * num1;
					stack.push(res + "");
				} else if (item.equals("/")) {
					res = num2 / num1;
					stack.push(res + "");
				}
			}
		}
		res = Integer.parseInt(stack.pop());
		return res;
	}

全家桶:

public class InfixtoSufixExpresion {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		// String infix = "1+2*3-4";
		String infix = "1+((2+3)*4)-5";
		String resSufix = "";
		for (String string : exchange(getList(infix))) {
			resSufix = resSufix.concat(" " + string);
		}
		String resExpre = resSufix;
		System.out.println("中缀表达式是:"+getList(infix));
		System.out.println("得到的后缀表达式是:" + resExpre);
		
		int res = calculator(exchange(getList(infix)));
		System.out.println("计算结果是:" + res);
	}

	public static List<String> getList(String str) {
		List<String> list = new ArrayList<String>();
		String[] string = str.split("");
		for (String ele : string) {
			list.add(ele);
		}
		//System.out.println(list);
		return list;
	}

	public static int perioity(String string) {
		char ch = string.charAt(0);
		if (ch == '+' || ch == '-') {
			return 0;
		} else if (ch == '*' || ch == '/') {
			return 1;
		} else {
			return -1;
		}
	}

	public static List<String> exchange(List<String> list) {
		// String resSufix = "";// 得到的后缀表达式
		Stack<String> stack1 = new Stack<String>();
		// Stack<String> stack2 = new Stack<String>();
		// 说明:stack2这个栈中途没有出栈操作而且最后需要逆序操作,所以可以直接用一个ArrayList替代
		List<String> stacklist = new ArrayList<String>();

		for (String item : list) {
			// 对item进行判断
			if (item.matches("\\d+")) {// 是数字
				// stack2.push(item);
				stacklist.add(item);
			} else {// 是符号,按照运算符和括号分别讨论
				switch (item) {
				case "+":
					if (stack1.empty() || stack1.peek() == "(") {
						stack1.push(item);
						break;
					} else if (perioity(item) > perioity(stack1.peek()) && stack1.peek() != "(") {
						stack1.push(item);
						break;
					} else {
						while (true) {
							// stack2.push(stack1.pop());
							stacklist.add(stack1.pop());
							if (stack1.empty() || stack1.peek() == "(" || perioity(item) > perioity(stack1.peek())) {
								stack1.push(item);
								break;
							}
						}
					}

					break;
				case "-":
					if (stack1.empty() || stack1.peek() == "(") {
						stack1.push(item);
						break;
					} else if (perioity(item) > perioity(stack1.peek()) && stack1.peek() != "(") {
						stack1.push(item);
						break;
					} else {
						while (true) {
							// stack2.push(stack1.pop());
							stacklist.add(stack1.pop());
							if (stack1.empty() || stack1.peek() == "(" || perioity(item) > perioity(stack1.peek())) {
								stack1.push(item);
								break;
							}
						}
					}
					break;
				case "*":
					if (stack1.empty() || stack1.peek() == "(") {
						stack1.push(item);
						break;
					} else if (perioity(item) > perioity(stack1.peek()) && stack1.peek() != "(") {
						stack1.push(item);
						break;
					} else {
						while (true) {
							// stack2.push(stack1.pop());
							stacklist.add(stack1.pop());
							if (stack1.empty() || stack1.peek() == "(" || perioity(item) > perioity(stack1.peek())) {
								stack1.push(item);
								break;
							}
						}
					}
					break;
				case "/":
					if (stack1.empty() || stack1.peek() == "(") {
						stack1.push(item);
						break;
					} else if (perioity(item) > perioity(stack1.peek()) && stack1.peek() != "(") {
						stack1.push(item);
						break;
					} else {
						while (true) {
							// stack2.push(stack1.pop());
							stacklist.add(stack1.pop());
							if (stack1.empty() || stack1.peek() == "(" || perioity(item) > perioity(stack1.peek())) {
								stack1.push(item);
								break;
							}
						}
					}
					break;
				case "(":
					stack1.push(item);
					break;
				case ")":// 这里消除括号有问题
					// 问题出现在:我写的是stack1.peek()!="("改成用equals()后不再报错
					while (!stack1.peek().equals("(")) {// 这一行报错,提示栈空的异常:EmptyStackException
						// stack2.push(stack1.pop());
						stacklist.add(stack1.pop());
					}
					// 新的问题,(没有出栈,结果输出显示有两个(,问题出现在这个if上
					 // if (stack1.peek().equals("(")) { stack1.pop(); break; }
					stack1.pop();
					break;
				default:
					System.out.println("运算符不合法");
					break;
				}
			}
		} // 入栈结束,开始出栈
		while (!stack1.empty()) {
			// stack2.push(stack1.pop());
			stacklist.add(stack1.pop());
		}
		return stacklist;
	}

	public static int calculator(List<String> ls) {
		// 进行计算
		int num1 = 0, num2 = 0;
		int res = 0;
		Stack<String> stack = new Stack();
		// 对List的数据进行判断,如果是数就存到栈中,如果是运算符就取出栈顶和次顶数据进行计算,计算结果存到栈中,然后继续判断List数据
		for (String item : ls) {// 遍历ls
			if (item.matches("\\d+")) {
				stack.push(item);
			} else {
				num1 = Integer.parseInt(stack.pop());
				num2 = Integer.parseInt(stack.pop());
				if (item.equals("+")) {
					res = num2 + num1;
					stack.push(res + "");
				} else if (item.equals("-")) {
					res = num2 - num1;
					stack.push(res + "");
				} else if (item.equals("*")) {
					res = num2 * num1;
					stack.push(res + "");
				} else if (item.equals("/")) {
					res = num2 / num1;
					stack.push(res + "");
				}
			}
		}
		res = Integer.parseInt(stack.pop());
		return res;
	}
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值