中缀表达式转后缀表达式思路分析及代码实现

中缀表达式转后缀表达式

思路步骤分析

  1. 初始化两个栈:运算符栈s1和储存中间结果的栈s2;
  2. 从左至右扫描中缀表达式;
  3. 遇到操作数时,将其压52;
  4. 遇到运算符时,比较其与s1栈顶运算符的优先级:
  • (1)如果s1为空,或栈顶运算符为左括号“(",则直接将此运算符入栈;
  • (2)否则,若优先级比栈顶运算符的高,也将运算符压入s1;
  • (3)否则,将s1栈顶的运算符弹出并压入到s2中,再次转到(4.1)与s1中新的栈顶运算符相比较;
    5. 遇到括号时:
  • (1)如果是左括号“(",则直接压入s1
  • (2)如果是右括号“)",则依次弹出s1栈顶的运算符,并压入s2,直到遇到左括号为止,此时将这一对括号丢弃
  1. 重复步骤2至5,直到表达式的最右边
  2. 将s1中剩余的运算符依次弹出并压入s28)依次弹出s2中的元素并输出,结果的逆序即为中缀表达式对应的后缀表达式

例:中缀表达式1+((2+3)*4)-5 ==> 后缀表达式1 2 3 + 4 * 5 -
在这里插入图片描述先将中缀表达式存放在一个ArrayList中,因为在list中更方便后面的遍历。
在这里插入图片描述

代码实现

public static void main(String[] args) {
		// 将中缀表达式转后缀表达式
		// 1.中缀表达式1+((2+3)*4)-5 ==> 后缀表达式1 2 3 + 4 * 5 -
		// 2.因为直接对Str进行操作不方便,因此将1+((2+3)*4)-5中缀表达式对应的list
		// 即1+((2+3)*4)-5 ==> Arraylist[1,+,(,(,2,+,3,),*,4,),-,5]
		String expression = "1+((2+3)*4)-5";
		List<String> infixExpressionList = toInfixExpressionList(expression);
		System.out.println(infixExpressionList);
		}
		// 方法:将中缀表达式转成list
	public static List<String> toInfixExpressionList(String s) {
		// 定义一个list存放中缀表达式对应的内容
		List<String> ls = new ArrayList<String>();
		int i = 0;// 用于遍历中缀表达式字符串
		String str;// 多位数的拼接
		char c;// 每遍历一个字符就存放到c中
		do {
			// 如果c是一个非数字,就加入到ls里面
			if ((c = s.charAt(i)) < 48 || (c = s.charAt(i)) > 57) {
				ls.add("" + c);
				i++;// i后移
			} else {// 如果是一个数,考虑多位数的问题
				str = "";// str置空
				while (i < s.length() && (c = s.charAt(i)) >= 48 && (c = s.charAt(i)) <= 57) {
					str += c;// 拼接
					i++;
				}
				ls.add(str);
			}
		} while (i < s.length());
		return ls;
	}

整体代码实现

结果图

在这里插入图片描述

String expression = "1+((2+3)*4)-5";
		List<String> infixExpressionList = toInfixExpressionList(expression);
		System.out.println("中缀表达式对应的List=" + infixExpressionList);
		List<String> suffixExpressionList = parseSuffixExpressionList(infixExpressionList);
		System.out.println("后缀表达式对应的List=" + suffixExpressionList);
System.out.printf("expression=%d",calculate(suffixExpressionList));
		// 即Arraylist[1,+,(,(,2,+,3,),*,4,),-,5]==>ArrayList[1,2,3,+,4,*,5,-]
	// 方法:将中缀表达式的list=>后缀表达式的list
	public static List<String> parseSuffixExpressionList(List<String> ls) {
		// 定义两个栈
		Stack<String> s1 = new Stack<String>();// 符号栈
		// 说明:因为s2在整个转换的过程中没有pop的操作,而且后期还要逆序输出所以我们使用List<String>来替代s2
		// Stack<String>s2=new Stack<String>();
		List<String> s2 = new ArrayList<String>();

		// 遍历ls
		for (String item : ls) {
			// 如果是一个数就入s2
			if (item.matches("\\d+")) {
				s2.add(item);
			} else if (item.equals("(")) {
				s1.push(item);
			} else if (item.equals(")")) {
				// 如果是右括号“)",则依次弹出s1栈顶的运算符,并压入s2,直到遇到左括号为止,此时将这一对括号丢弃
				while (!s1.peek().equals("(")) {
					s2.add(s1.pop());
				}
				s1.pop();// !!!将(弹出s1栈,消除小括号
			} else {
				// 当item的优先级小于等于栈顶运算符的优先级
				// 将s1栈顶的运算符弹出并加入到s2中,再次转到(4.1)与s1中新的栈顶运算符相比较
				// 缺少一个比较优先级的方法
				while (s1.size() != 0 && Operation.getValue(s1.peek()) >= Operation.getValue(item)) {
					s2.add(s1.pop());
				}
				// 还需要item压入栈中
				s1.push(item);
			}
		}
		// 将s1中剩余的运算符加入到s2中
		while (s1.size() != 0) {
			s2.add(s1.pop());
		}
		return s2;// 因为是存放到List中因此正常输出就是后缀表达式

	}

	// 方法:将中缀表达式转成list
	public static List<String> toInfixExpressionList(String s) {
		// 定义一个list存放中缀表达式对应的内容
		List<String> ls = new ArrayList<String>();
		int i = 0;// 用于遍历中缀表达式字符串
		String str;// 多位数的拼接
		char c;// 每遍历一个字符就存放到c中
		do {
			// 如果c是一个非数字,就加入到ls里面
			if ((c = s.charAt(i)) < 48 || (c = s.charAt(i)) > 57) {
				ls.add("" + c);
				i++;// i后移
			} else {// 如果是一个数,考虑多位数的问题
				str = "";// str置空
				while (i < s.length() && (c = s.charAt(i)) >= 48 && (c = s.charAt(i)) <= 57) {
					str += c;// 拼接
					i++;
				}
				ls.add(str);
			}
		} while (i < s.length());
		return ls;
	}
	public static int calculate(List<String> ls) {
		// 创建一个栈,只需要一个栈即可
		Stack<String> stack = new Stack<String>();
		// 遍历ls
		for (String item : ls) {
			// 使用一个正则表达式来取出数
			if (item.matches("\\d+")) {// 匹配多位数
				// 入栈
				stack.push(item);
			} else {
				// pop出两个数,并运算,再入栈
				int num2 = Integer.parseInt(stack.pop());
				int num1 = Integer.parseInt(stack.pop());
				int res = 0;
				if (item.equals("+")) {
					res = num1 + num2;
				} else if (item.equals("-")) {
					res = num1 - num2;
				} else if (item.equals("*")) {
					res = num1 * num2;
				} else if (item.equals("/")) {
					res = num1 / num2;
				} else {
					throw new RuntimeException("运算符有误");
				}
				// 把res入栈
				stack.push("" + res);
			}
		}
		// 最后留在stack的数据时运算结果
		return Integer.parseInt(stack.pop());
	}
	
	// 返回优先级高低的类(Operation)
class Operation {
	public static int ADD = 1;
	public static int SUB = 1;
	public static int MUL = 2;
	public static int DIV = 2;
	// 返回对应的优先级数字
	public static int getValue(String operation) {
		int result = 0;
		switch (operation) {
		case "+":
			result = ADD;
			break;
		case "-":
			result = SUB;
			break;
		case "*":
			result = MUL;
			break;
		case "/":
			result = DIV;
			break;
		default:
			System.out.println("不存在该运算符");
			break;
		}
		return result;
	}
}

发布了39 篇原创文章 · 获赞 31 · 访问量 6121

猜你喜欢

转载自blog.csdn.net/lu_long/article/details/103096495