棧---1、中綴表示式到字尾表示式的轉化 2、求解字尾表示式的值
阿新 • • 發佈:2019-02-03
一、中綴表示式及字尾表示式
例:典型的計算順序為2+2*3+5=?
上面這個表示式也被成為中綴表示式。
它可以表示為2*3的乘積存為a1,讓a1與2相加得到a2,最後5和a2相加得到a3,a3即為該表示式的值。
這種計算順序可書寫成:223*+5+。這便是字尾表示式。
二、實現程式碼
中綴表示式到字尾表示式的轉化:
public class Question {
public static void getResult() {
Stack<Character> stack = new Stack<>();
String expression;
Character token;
int i = 0;
Scanner scanner = new Scanner(System.in);
expression = scanner.next();
while ((token = expression.charAt(i++)) != '=') {
if (token >= 'a' && token <= 'z') {
System.out.print(token + " ");// 非操作符直接輸出
} else {
switch (token) {
case ')':// 1、移除棧中元素直到(,包括(
while (!stack.isEmpty() && stack.peek() != '(') {
System.out.print(stack.pop() + " ");
}
stack.pop();// 移除(
break;
case '(' :// 2、(的優先順序最高,直接放入
stack.push(token);
break;
case '^':// 取冪運算子//3、除了(,其它操作符均彈出
while (!stack.isEmpty() && !(stack.peek() == '^') && !(stack.peek() == '(')) {
System.out.print(stack.pop() + " ");
}
break;
case '*':
case '/':
// 彈出棧元素,碰見比*,/優先順序低的為止
while (!stack.isEmpty() && stack.peek() != '+' && stack.peek() != '-' && stack.peek() != '(') {
System.out.print(stack.pop() + " ");
}
stack.push(token);
break;
case '+':
case '-':
// 除了(外,從棧中彈出元素,直至遇見一個優先順序更低的元素
while (!stack.isEmpty() && stack.peek() != '(') {
System.out.print(stack.pop() + " ");
}
stack.push(token);
break;
}
}
}
while (!stack.isEmpty()) {
System.out.print(stack.pop());
}
System.out.println();
}
public static void main(String[] args) {
// 中綴:a+b*c+(d*e+f)*g=
// 字尾:a b c * + d e * f + g *+
getResult();
}
}
字尾表示式的計算:
public class Question {
public static double getResult(){
Stack<Double> stack=new Stack<>();
String token;
Double a,b,result=0.0;
boolean isNumber;
Scanner scanner=new Scanner(System.in);
token=scanner.next();
//等於號作為結束符號
while(token.charAt(0)!='='){
try {
isNumber=true;
result=Double.parseDouble(token);
} catch (Exception e) {
isNumber=false;//發生異常說明輸入的為字母,否則為數字
}
if(isNumber){
stack.push(result);//數字放入棧中
}else{
//如果是運算子,則從棧中取出兩個數完成物件的操作再放入棧中
switch (token.charAt(0)) {
case '+':
a=stack.pop();
b=stack.pop();
stack.push(a+b);
break;
case '-':
a=stack.pop();
b=stack.pop();
stack.push(a-b);
break;
case '*':
a=stack.pop();
b=stack.pop();
stack.push(a*b);
break;
case '/':
a=stack.pop();
b=stack.pop();
stack.push(a/b);
break;
case '^'://取冪運算
a=stack.pop();
b=stack.pop();
stack.push(Math.pow(b, a));
break;
default:
break;
}
}
token=scanner.next();
}
return stack.peek();//返回棧頂元素
}
public static void main(String[] args) {
System.out.println(getResult());
/*
* 1
* 2
* 1
* +
* =
* 3.0
*/
}
}
三、總結
1、中綴到字尾的轉化主要就是:(特別情況)除非處理一個)時,否則絕對不會彈出(;(普通)彈出優先順序大於等於要處理的元素,直到遇見優先順序更低的為止。
2、通過棧的後進先出特性可以很好地計算字尾表示式的值。遇見一個數時就把它放入棧中,遇見一個運算子時,則該運算子就作用於該棧彈出的兩各數上,並把得到的結果放入棧中。
Life is a journey. What we should care about is not where it’s headed but what we see and how we feel.