NYOJ 267鬱悶的C小加(二)

題目大意:將一箇中綴表達式轉爲後綴表達式,並計算結果,這個中綴轉後綴和表達式求值的結合!!


我的理解:先說一下,我對表達式的中綴、後綴的理解。中綴式符合人們的書寫習慣,但是需要考慮運算符的優先級,括號也是有優先級的,

雖然它不參加運算,但是它改變了局部表達式的優先級!!!!!而後綴變大時,是不需要考慮優先級別的,它的書寫順序和計算

順序是一致的,我們手算的順序其實和後綴變大時的書寫順序是一樣的!!!


思路:遍歷表達式,遇到數字和小數點就直接輸出(多次試驗,發現後綴中數字的順序和中綴式一樣的),遇到運算符就利用棧來確定它們的順序。

數字在輸出的時候也要進到數據棧裏,以便求出整個表達式的值!!!


數據結構:一個運算符棧,一個數據棧


上碼:

import java.io.BufferedInputStream;
import java.util.Scanner;
import java.util.Stack;

public class 鬱悶的新小加二 {
	public static void main(String[] args) {
		Scanner sc = new Scanner(new BufferedInputStream(System.in));
		int cases, len;
		String input, numStr;

		Stack<Double> num = new Stack<Double>();
		Stack<Character> op = new Stack<Character>();

		cases = sc.nextInt();
		while (cases-- > 0) {
			op.clear();
			num.clear();

			input = sc.next();
			len = input.length() - 1;// 去掉'='
			numStr = "";

			for (int i = 0; i < len; i++) {
				char c = input.charAt(i);
				if (Character.isDigit(c) || c == '.') {// 數字和.
					numStr += c;
					System.out.print(c);
				} else if (c == '(') {// '('
					op.push(c);
				} else if (isSymbol(c)) {// 運算符
					if (!numStr.equals("")) {//避免遇到前面是')',(此時numStr已經被清空了),當前c是運算符!!!
						num.push(Double.valueOf(numStr));
						numStr = "";
					}

					if (!op.isEmpty() && rank(op.peek()) >= rank(c)) {
						while (!op.isEmpty() && rank(op.peek()) >= rank(c)) {
							double num2 = num.pop();
							double num1 = num.pop();
							char op1 = op.pop();
							System.out.print(op1);
							num.push(cal(num1, num2, op1));
						}
					}
					op.push(c);
				} else {// ')'
					if (!numStr.equals("")) {//避免是'))',因爲遇到第一個')'時,numStr就是空了!!
						num.push(Double.valueOf(numStr));
						numStr = "";
					}
					while (op.peek() != '(') {//一直運算,直到遇到'('
						double num2 = num.pop();
						double num1 = num.pop();
						char op1 = op.pop();
						System.out.print(op1);
						num.push(cal(num1, num2, op1));
					}
					op.pop();// 彈出'('
				}
			}
			if (!numStr.equals("")) {//避免表達式的最後就是數字!!!因爲只有遇到'-+*/)'時,纔會把數字壓入棧
				num.push(Double.valueOf(numStr));
			}
			while (!op.isEmpty()) {//當只有一個運算符的時候!!!
				double num2 = num.pop();
				double num1 = num.pop();
				char op1 = op.pop();
				System.out.print(op1);
				num.push(cal(num1, num2, op1));
			}
			System.out.printf("=\n%.2f", num.pop());
			if (cases > 0) {
				System.out.println();
			}
		}

		sc.close();
	}

	static boolean isSymbol(char c) {
		return c == '+' || c == '-' || c == '*' || c == '/';
	}

	static int rank(char c) {
		if (c == '-' || c == '+') {
			return 1;
		}
		if (c == '*' || c == '/') {
			return 2;
		}
		return 0;//把'('也當成一個運算符!!!!
	}

	static double cal(double num1, double num2, char op) {
		switch (op) {
		case '-':
			num1 -= num2;
			break;
		case '+':
			num1 += num2;
			break;
		case '*':
			num1 *= num2;
			break;
		case '/':
			num1 /= num2;
			break;
		}
		return num1;
	}
}


發佈了38 篇原創文章 · 獲贊 2 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章