題目一:請利用Stack把字符串中綴表達式編譯爲後綴表達式,然後再利用棧執行後綴表達式獲得計算結果。
題目二:請把帶變量的中綴表達式編譯爲後綴表達式,執行後綴表達式時,傳入變量的值並獲得計算結果。
- 中綴表達式轉爲後綴表達式:
1.按次序讀取中綴表達式的字符。
2.讀到一個操作數的時候,立即放入到輸出中。
3.讀到操作符“+”,“-”,“*”,“/”,則從棧中彈出棧元素並輸出,直到遇到優先級更低或者“(”的爲止操作符爲止(該元素不出棧)。
4.讀到操作符“(”,則直接把“(”壓入棧中。
5.讀到操作符“)”,則從棧中彈出棧元素並輸出,直到遇到第一個“(”爲止。其中“(”不再添加到輸出中,而是直接捨棄。
6.當輸入爲空時,把棧裏的操作符全部依次彈出並輸出。 - 根據後綴表達式 計算結果:
1.按次序讀取後綴表達式的每一個字符。
2.讀取到操作數時,把操作數壓入棧中。
3.讀取到操作符時,對棧頂的2個操作數做相應運算,要注意操作數的前後順序。結果壓入棧中。
4.讀取完所有的字符後,彈出棧。得到的值就是所求結果。
題目一代碼:
import java.util.Deque;
import java.util.LinkedList;
import java.util.*;
public class Main {
public static void main(String[] args) {
// --------- stack 中綴表達式編譯爲後綴表達式 ---------------------
String exp = "1 + 2 * (9 - 5)";
SuffixExpression se = compile(exp);
Float result = se.execute();
System.out.println(exp + " = " + result + " " + (result == 1 + 2 * (9 - 5) ? "✓" : "✗"));
}
static SuffixExpression compile(String exp) {
// TODO:中綴轉後綴
// 1.按次序讀取中綴表達式的字符。
// 2.讀到一個操作數的時候,立即放入到輸出中。
// 3.讀到操作符“+”,“-”,“*”,“/”,則從棧中彈出棧元素並輸出,直到遇到優先級更低或者“(”的爲止操作符爲止(該元素不出棧)。
// 4.讀到操作符“(”,則直接把“(”壓入棧中。
// 5.讀到操作符“)”,則從棧中彈出棧元素並輸出,直到遇到第一個“(”爲止。其中“(”不再添加到輸出中,而是直接捨棄。
// 6.當輸入爲空時,把棧裏的操作符全部依次彈出並輸出。
Deque<Character> rs= new LinkedList<>();
char[] cexp = exp.toCharArray();
String out = "";
for(int i = 0; i < cexp.length; i++) {
char ch = cexp[i];
if (ch == ' ') continue;
if (ch >= '0' && ch <= '9') {
out += ch;
continue;
}
if (ch == '(') {
rs.push(ch);
}
if (ch == '+' || ch =='-') {
while(!rs.isEmpty() && (rs.peek() != '(')) {
out += rs.pop();
}
rs.push(ch);
continue;
}
if (ch == '*' || ch =='/') {
while(!rs.isEmpty() && (rs.peek() == '*' || rs.peek() == '/')) {
out += rs.pop();
}
rs.push(ch);
continue;
}
if (ch == ')') {
while(!rs.isEmpty() && rs.peek() != '(') {
out += rs.pop();
}
rs.pop();
continue;
}
}
while(!rs.isEmpty()) out += rs.pop();
System.out.println(out);
return new SuffixExpression(out);
}
}
class SuffixExpression {
String exp;
public SuffixExpression(String exp) {
this.exp = exp;
}
public float execute() {
//TODO:根據後綴表達式 計算結果
// 1.按次序讀取後綴表達式的每一個字符。
// 2.讀取到操作數時,把操作數壓入棧中。
// 3.讀取到操作符時,對棧頂的2個操作數做相應運算,要注意操作數的前後順序。結果壓入棧中。
// 4.讀取完所有的字符後,彈出棧。得到的值就是所求結果。
Deque<Float> cs= new LinkedList<>();
char[] cexp = exp.toCharArray();
for (int i = 0; i < cexp.length; i++) {
char ch = cexp[i];
if (ch>='0' && ch<='9') {
cs.push(Float.valueOf(ch - '0'));
continue;
} else {
cs.push(calculate(ch, cs.pop(), cs.pop()));
}
}
System.out.println(exp);
return cs.pop();
}
public float calculate(char op, Float f1, Float f2) {
if (op == '+') return f1 + f2;
else if (op == '-') return f2 -f1;
else if (op == '*') return f1 * f2;
else if (op == '/') return f2/f1;
else return Float.valueOf(-0);
}
}
題目二代碼:
import java.util.*;
public class Main {
public static void main(String[] args) {
String exp = "x + 2 * (y - 5)";
SuffixExpression se = compile(exp);
// System.out.println(se);
Map<String, Float> env = Map.of("x", 5f, "y", 6f);// 使用Map保存變量值
float result = se.execute(env);
System.out.println(exp + " = " + result + " " + (result == 5 + 2 * (6 - 5) ? "✓" : "✗"));
}
static SuffixExpression compile(String exp) {
// TODO:中綴轉後綴
// 1.按次序讀取中綴表達式的字符。
// 2.讀到一個操作數的時候,立即放入到輸出中。
// 3.讀到操作符“+”,“-”,“*”,“/”,則從棧中彈出棧元素並輸出,直到遇到優先級更低或者“(”的爲止操作符爲止(該元素不出棧)。
// 4.讀到操作符“(”,則直接把“(”壓入棧中。
// 5.讀到操作符“)”,則從棧中彈出棧元素並輸出,直到遇到第一個“(”爲止。其中“(”不再添加到輸出中,而是直接捨棄。
// 6.當輸入爲空時,把棧裏的操作符全部依次彈出並輸出。
Deque<Character> rs= new LinkedList<>();
char[] cexp = exp.toCharArray();
String out = "";
for(int i = 0; i < cexp.length; i++) {
char ch = cexp[i];
if (ch == ' ') continue;
if (ch >= '0' && ch <= '9') {
out += ch;
continue;
}
if (ch == 'x' || ch == 'y') {
out +=ch;
continue;
}
if (ch == '(') {
rs.push(ch);
}
if (ch == '+' || ch =='-') {
while(!rs.isEmpty() && (rs.peek() != '(')) {
out += rs.pop();
}
rs.push(ch);
continue;
}
if (ch == '*' || ch =='/') {
while(!rs.isEmpty() && (rs.peek() == '*' || rs.peek() == '/')) {
out += rs.pop();
}
rs.push(ch);
continue;
}
if (ch == ')') {
while(!rs.isEmpty() && rs.peek() != '(') {
out += rs.pop();
}
rs.pop();
continue;
}
}
while(!rs.isEmpty()) out += rs.pop();
return new SuffixExpression(out);
}
}
class SuffixExpression {
String exp;
public SuffixExpression(String exp) {
this.exp = exp;
}
// 後綴表達式計算
public float execute(Map<String, Float> env) {
//TODO:根據後綴表達式 計算結果
// 1.按次序讀取後綴表達式的每一個字符。
// 2.讀取到操作數時,把操作數壓入棧中。
// 3.讀取到操作符時,對棧頂的2個操作數做相應運算,要注意操作數的前後順序。結果壓入棧中。
// 4.讀取完所有的字符後,彈出棧。得到的值就是所求結果。
Deque<Float> cs= new LinkedList<>();
char[] cexp = this.exp.toCharArray();
for (int i = 0; i < cexp.length; i++) {
char ch = cexp[i];
if (ch>='0' && ch<='9') {
cs.push(Float.valueOf(ch - '0'));
continue;
} else if(ch =='x' || ch =='y') {
String sc = Character.toString(ch);
cs.push(env.get(sc));//利用key讀取變量x, y的值
continue;
}
else{
cs.push(calculate(ch, cs.pop(), cs.pop()));
}
}
System.out.println(exp);
return cs.pop();
}
//根據運算符返回計算結果
public float calculate(char op, float f1, float f2) {
if (op == '+') return f1 + f2;
else if (op == '-') return f2 - f1;
else if (op == '*') return f1 * f2;
else if (op == '/') return f2 / f1;
else return Float.valueOf(-0);
}
}