科學計算器的實現(java語言)

實現科學計算器:

就要想它的算法,這裏應用的是經典的後綴表達式的應用。

後綴表達式:

一種不需要括號的後綴表達法,

如:1+2*3*(1+2)+(3-2)*(5/2) 爲中綴表達法;

它所對應的後綴表達式爲:123*12+*+32-52/*+ 

中綴表達式轉後綴表達式:

可以用棧進行入算術符進行轉換,

然後進行優先級的判斷,進行出入棧的操作;

後綴表達式計算結果:

遍歷後綴表達式,遇到數字進行入棧,遇到符號彈出2個數進行計算,再次入棧。

下面試java的實現代碼:

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.Stack;
/**
 * 科學表達式: 總的計算思路爲:
 1.將中綴表達式轉化爲後綴表達式(棧是用來進出運算的符號)
 2.將後綴表達式進行運算得出結果(棧是用來進出運算的數字)
 * 
 * @author chennan
 *
 */
public class Calculate {
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		System.out.println("請輸入一個包含加減乘除的表達式:");
		String s=sc.nextLine();
		System.out.println(s+"="+calculate(s));
	}

	public static double calculate(String expre) {
		List<String> num=transformEnd(expre);
		Stack<Double> stack = new Stack<>();
		double sum = 0;
		while (!num.isEmpty()) {
			String temp = String.valueOf(num.remove(0));
			if (isNamber(temp)) {
				double s=Double.parseDouble(temp);
				stack.push(s);
			} else {
				double a=stack.pop();
				double b=stack.pop();
				double c=calTwo(b,a,temp);
				stack.push(c);
			
			}
		}
		sum=stack.pop();
		return sum;
	}

	private static double calTwo(double a, double b, String opr) {
		double sum = 0;
		switch (opr) {
		case "+":
			sum = a + b;
			break;
		case "-":
			sum = a - b;
			break;
		case "*":
			sum = a * b;
			break;
		case "/":
			sum = a / b;
			break;
		}
		return sum;
	}

	/**
	 * 
	 * 1.將中綴表達式轉化爲後綴表達式(棧是用來進出運算的符號)
	 */
	public static List<String> transformEnd(String expre) {
		List<String> sb = new ArrayList<>();
		Stack<String> stack = new Stack<>();
		expre = expre.replaceAll("(\\D)", "o$1o");
		String[] esp = expre.trim().split("o");

		for (int i = 0; i < esp.length; i++) {
			String s = esp[i].trim();

			if (isNamber(s)) {
				// 如果是數字則輸出
				sb.add(s);
			} else if (!s.isEmpty()) {

				if (s.charAt(0) == ')') {
					while (stack.peek().charAt(0) != '(') {
						sb.add(stack.pop());
					}
					stack.pop();
				} else {
					if (!stack.isEmpty() && !isMaxExp(s.charAt(0), stack.peek().charAt(0))) {
						while (!stack.isEmpty() && !isMaxExp(s.charAt(0), stack.peek().charAt(0))) {
							sb.add(stack.pop());
						}
						stack.push(s);
					} else {
						stack.push(s);
					}
				}
			}
		}
		while (!stack.isEmpty()) {
			sb.add(stack.pop());
		}
		return sb;
	}

	// 判斷是否是數字
	private static boolean isNamber(String str) {
		try {
			Double.parseDouble(str);

		} catch (RuntimeException e) {
			return false;
		}
		;
		return true;
	}

	// 判斷是否進棧
	private static boolean isMaxExp(char exp1, char exp2) {
		if (exp1 == '(')
			return true;
		if (exp2 == ')')
			return true;
		if (transExp(exp1) > transExp(exp2))
			return true;

		return false;

	}

	private static int transExp(char exp) {
		int re = 0;
		switch (exp) {
		case '*':
		case '/':
			re = 2;
			break;
		case '+':
		case '-':
			re = 1;
			break;
		}
		return re;
	}

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章