栈实现简单计算器(后缀表达式)

目录

一、后缀表达式举例

二、需求

三、字符串扫描法

思路分析    

代码实现

四、遍历ArrayList法

思路分析

代码实现


一、后缀表达式举例

      A:a+b的后缀表达式为ab+;

      B:(a+b)*c-(a+b)/e的后缀表达式为ab+c*ab+e/-;

二、需求

     A:输入一个后缀表达式,并用栈计算结果;

     B:支持小括号和多位数整数;

三、字符串扫描法

  • 思路分析    

     A:和之前的中缀表达式类似,对字符串自左到右扫描,定义一个数栈,用来存放扫描到的数字;
     B:当扫描到运算符时,弹出数栈中两个元素,运算后再入栈;
     C:重复A,B过程;

  • 代码实现

package cn.itcast_03;

import java.util.Stack;

/*
 *需求:
 *   A:输入一个后缀表达式(使用空格隔开),并用栈计算结果;
 *   B:支持小括号和多位数整数;
 *分析:
 *   A:对字符串自左到右扫描,定义一个数栈,用来存放扫描到的数字;
 *   B:当扫描到运算符时,弹出数栈中两个元素,运算后再入栈;
 *   C:重复A,B过程; 
 */
public class PolandNotation {
	public static void main(String[] args) {
		// 定义给逆波兰表达式
		String expression = "3 4 + 5 * 6 -";// (3+4)*5-6
		// 定义数栈
		Stack<Integer> numStack = new Stack<Integer>();

		// 定义相关变量
		char ch = ' ';
		String keepNum = "";

		for (int i = 0; i < expression.length(); i++) {
			ch = expression.substring(i, i + 1).charAt(0);
			if (isOper(ch)) {
				function(numStack, ch);
			} else if (ch == ' ') {
				continue;
			} else {
				// 是数字
				keepNum += ch;
				ch = expression.substring(i + 1, i + 2).charAt(0);
				if (ch == ' ') {
					numStack.push(Integer.parseInt(keepNum));
					keepNum = "";
				}
			}
		}
		System.out.println(numStack.pop());
	}

	// 定义计算后出栈入栈功能
	public static void function(Stack<Integer> numStack, char oper) {
		int num1 = 0;
		int num2 = 0;
		int res = 0;
		num1 = numStack.pop();
		num2 = numStack.pop();
		res = cal(num1, num2, oper);
		numStack.push(res);
	}

	// 判断字符是否为运算符
	public static boolean isOper(int ch) {
		return ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '(' || ch == ')';
	}

	// 定义计算函数
	public static int cal(int num1, int num2, char ch) {
		int res = 0;

		switch (ch) {
		case '+':
			res = num1 + num2;
			break;
		case '-':
			res = num2 - num1;// 这个地方就想象2-1时的情景
			break;
		case '*':
			res = num1 * num2;
			break;
		case '/':
			res = num2 / num1;
			break;
		default:
			break;
		}

		return res;
	}
}

四、遍历ArrayList法

  • 思路分析

     A:将表示后缀表达式的字符串传递到ArrayList中;

     B:通过遍历ArrayList,遇到数字则压入栈,遇到符号弹出栈中两个元素,并运算后,将结果入栈;

     C:最后pop出栈中最后一个元素;

  • 代码实现

package cn.itcast_03;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

/*
 *需求:
 *   A:输入一个后缀表达式(使用空格隔开),并用栈计算结果;
 *   B:支持小括号和多位数整数;
 *分析:
 *   A:先将字符串中的字符放到ArrayList中
 *   B:将ArrayList传递给一个方法,遍历ArrayList,配合栈完成计算 
 */
public class PolandNotation {
	public static void main(String[] args) {
		// 定义给逆波兰表达式
		String expression = "3 4 + 5 * 6 - 2 1 / -";// (3+4)*5-6-(2/1)

		List<String> rpnList = getListString(expression);
		System.out.println("计算的结果为:" + calculate(rpnList));

	}

	// 将字符串中的字符放到ArrayList中
	public static List<String> getListString(String expression) {
		// 将字符串分割
		String[] split = expression.split(" ");
		List<String> list = new ArrayList<String>();
		for (String ele : split) {
			list.add(ele);
		}
		return list;
	}

	// 完成对后缀表达式的计算
	public static int calculate(List<String> ls) {
		// 创建一个栈
		Stack<String> numStack = new Stack<String>();
		// 遍历ls
		for (String item : ls) {
			// 使用正则表达式取出数字,\\d+表示多位数
			if (item.matches("\\d+")) {
				numStack.push(item);
			} else {
				function(numStack, item.charAt(0));
			}
		}
		return Integer.parseInt(numStack.pop());
	}

	// 定义计算后出栈入栈功能
	public static void function(Stack<String> numStack, char oper) {
		int num1 = 0;
		int num2 = 0;
		int res = 0;
		num1 = Integer.parseInt(numStack.pop());
		num2 = Integer.parseInt(numStack.pop());
		res = cal(num1, num2, oper);
		numStack.push(res + "");
	}

	// 定义计算函数
	public static int cal(int num1, int num2, char ch) {
		int res = 0;

		switch (ch) {
		case '+':
			res = num1 + num2;
			break;
		case '-':
			res = num2 - num1;// 这个地方就想象2-1时的情景
			break;
		case '*':
			res = num1 * num2;
			break;
		case '/':
			res = num2 / num1;
			break;
		default:
			break;
		}

		return res;
	}
}
发布了62 篇原创文章 · 获赞 9 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/Sruggle/article/details/103978761