Discuss / Java / 练习2

练习2

Topic source

package com.itranswarp.learnjava.test;

import java.util.Map;
import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* @author: 默苍璃
* @date: 2021-09-15 16:14
* <p>
* 请利用Stack把字符串中缀表达式编译为后缀表达式,然后再利用栈执行后缀表达式获得计算结果
*/
public class test03 {

public static void main(String[] args) {
String exp = "x + 2 * (y - 5)";
Map<String, Integer> env = Map.of("x", 1, "y", 9);
String change = change(exp);
int result = execute(change, env);
System.out.println(exp + " = " + result + " " + (result == 1 + 2 * (9 - 5) ? "✓" : "✗"));
}

/**
* 中缀表达式转换成后缀表达式 工具类
*
* @param exp
* @return
*/
static String change(String exp) {
// TODO: 1 2 9 5 - * +
//判断是否为数字 正则
Pattern pattern = Pattern.compile("[0-9xy]");
//判断是否为运算符 正则
Pattern pattern1 = Pattern.compile("[-+*/]");
//返回结果
StringBuilder result = new StringBuilder();

//储存中间结果的栈(结果栈)
Stack<String> s1 = new Stack<>();
//运算符栈
Stack<String> s2 = new Stack<>();

//字符串变char[]
char[] chars = exp.toCharArray();

for (char aChar : chars) {

String s = String.valueOf(aChar);
Matcher matcher = pattern.matcher(s);
Matcher matcher1 = pattern1.matcher(s);

//遇到操作数时,将其压s1(运算符栈)
if (matcher.matches()) {
s1.push(s);
}

//遇到运算符
if (matcher1.matches()) {

while (true) {
//如果s2(运算符栈)为空,或栈顶运算符为左括号“(”,则直接将此运算符入栈;
if (s2.size() == 0 || s2.peek().equals("(")) {
s2.push(s);
break;
}
//否则,若优先级比栈顶运算符的高,也将运算符压入s2(运算符栈);
if ((s.equals("*") || s.equals("/")) && (s2.peek().equals("+") || s2.peek().equals("-"))) {
s2.push(s);
break;
//否则,将s2栈顶的运算符弹出并压入到s1中,再次转到与s2中新的栈顶运算符相比较;
} else {
s1.push(s2.pop());
}
}
}

//遇到括号时
//如果是左括号"(",则直接压入s2(运算符栈)
if (s.equals("(")) {
s2.push(s);
}
//如果是右括号")",则依次弹出s2栈顶的运算符,并压入s1,直到遇到左括号为止,此时将这一对括号丢弃
if (s.equals(")")) {
for (int i = 0; i < s2.size(); i++) {
String pop = s2.pop();
if (!pop.equals("(")) {
s1.push(pop);
}
}
}
}

int size = s2.size();
for (int i = 0; i < size; i++) {
String pop = s2.pop();
s1.push(pop);
}

for (String s : s1) {
result.append(s);
}

return result.toString();
}

/**
* 中缀表达式 输出结果
*
* @return
*/
public static int execute(String exp, Map<String, Integer> env) {
// TODO:
//判断是否为数字 正则
Pattern pattern = Pattern.compile("[0-9xy]");
//判断是否为运算符 正则
Pattern pattern1 = Pattern.compile("[-+*/]");
//储存中间结果的栈(结果栈)
Stack<String> s1 = new Stack<>();

//获取变量x y
int x = 0;
int y = 0;
for (Map.Entry<String, Integer> entry : env.entrySet()) {
String key = entry.getKey();
if (key.equals("x")) {
x = entry.getValue();
}
if (key.equals("y")) {
y = entry.getValue();
}
}

//字符串变char[]
char[] chars = exp.toCharArray();

for (char aChar : chars) {
String s = String.valueOf(aChar);
Matcher matcher = pattern.matcher(s);
Matcher matcher1 = pattern1.matcher(s);

//遇到操作数时,直接扔到栈
if (matcher.matches()) {
s1.push(s);
}

//遇到运算符 弹出栈顶的两个元素,并计算 把结果压栈
if (matcher1.matches()) {
String x1 = s1.pop();
String y1 = s1.pop();

int i = 0;
int j = 0;

if (!x1.equals("x") && !x1.equals("y")) {
i = Integer.parseInt(x1);
}
if (!y1.equals("x") && !y1.equals("y")) {
j = Integer.parseInt(y1);
}

if (x1.equals("x")) {
i = x;
}
if (x1.equals("y")) {
i = y;
}
if (y1.equals("x")) {
j = x;
}
if (y1.equals("y")) {
j = y;
}

switch (s) {
case "+":
s1.push(Integer.toString(j + i));
break;
case "-":
s1.push(Integer.toString(j - i));
break;
case "*":
s1.push(Integer.toString(j * i));
break;
case "/":
s1.push(Integer.toString(j / i));
break;
default:
}
}

}
return Integer.parseInt(s1.pop());

}

}

练习1会了 练习二 应该 不成问题 

就是 改一下正则表达式 还有 弹出栈的时候 判断 一下xy


  • 1

Reply