實現科學計算器:
就要想它的算法,這裏應用的是經典的後綴表達式的應用。
後綴表達式:
一種不需要括號的後綴表達法,
如: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;
}
}