利用Stack進行四則運算表達式求值

題目一:請利用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);
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章