問題描述
程序設計中經常使用表達式,現在需要編寫程序,設計算法,利用棧,計算合法表達式結果。本題中表達式由含運算符+、-、*、/、(、)和整形常量復合而成。
程序代碼
import java.util.Scanner;
import java.util.Stack;
public class Main {
public static String convert2Postfix(String infix) {
char[] chars = infix.toCharArray(); //轉換為字符數組
Stack<Character> stack = new Stack<Character>(); //存放操作符
StringBuilder ans = new StringBuilder(infix.length()); //存放后綴表達式。用stringbuilder方便拼接
Character ch;
for (int i=0;i<chars.length;i++) {
Character c = chars[i];
switch (c) {
case '(':
stack.push(c);
break; //左括號直接入棧
case '*':
case '/':
while (!stack.isEmpty()) {
ch = stack.pop();
if (getPriority(ch) < 2) { //為+-操作或者(的時候,此時運算優先級低,停止彈出
stack.push(ch);
break;
} else ans.append(" " + ch);
}
stack.push(c);
ans.append(" ");
break;
case '+':
case '-':
Boolean a2 = (i!=0)&&(c=='-')&&(Character.isDigit(chars[i-1])); //表示-號前面為數字的時候
Boolean a3 = (i!=0)&&(c=='-')&&(chars[i-1]==')'); //表示-號前面為)的時候
if(a2.booleanValue()||a3.booleanValue()||c=='+') { //表示這是操作符意義上的-號或者這是加號
while (!stack.isEmpty()) {
ch = stack.pop();
if (ch == '(') { //+-的時候優先級比它低的只有(
stack.push('(');
break;
}
ans.append(" " + ch);
}
stack.push(c);
ans.append(" ");
break;
}else
{
ans.append("-"); //如果是表示負數的-號直接加到后綴表達式里面
}
case ')':
while(!stack.isEmpty()){
ch = stack.pop();
if(ch =='(')
break;
else
ans.append(" "+ch);
} //直到出現(號停止彈出
break;
default:ans.append(c); //普通數字字符直接拼接到后綴表達式里面
}
}
while (!stack.empty()) {
ans.append(" "+stack.pop());
}
return ans.toString();
}
public static int getPostfixValue(String postfix) {
String[] tokes = postfix.split(" "); //將后綴表達式按照空格分開
Stack<Integer> stack = new Stack<Integer>();
int value = 0;
for (String c : tokes) {
if (c.length()!=1 || Character.isDigit(c.charAt(0))) { //如果長度不等於1(包括-1)或者說長度為1的數就壓入到棧里
stack.push(Integer.parseInt(c));
} else if (c.length()==1 && isOperator(c.charAt(0))) { //為操作符的時候
int op1 = stack.pop();
int op2 = stack.pop();
int result;
switch (c.charAt(0)) {
case '*':
result = op1 * op2;
stack.push(result);
break;
case '/':
result = op2 / op1;
stack.push(result);
break;
case '+':
result = op1 + op2;
stack.push(result);
break;
case '-':
result = op2 - op1;
stack.push(result);
break;
}
}
}
return stack.pop();
}
private static int getPriority(char operator) {
int t = 0;
if (operator == '-' || operator == '+') {
t = 1;
} else if (operator == '*' || operator == '/') {
t = 2;
}
return t;
}//獲取優先級
private static boolean isOperator(char x) {
if(x=='-' || x=='+' || x=='*' || x=='/')
return true;
else
return false;
}//判斷是否為操作符
public static void main(String[] args)
{
Scanner cin = new Scanner(System.in);
String expression = cin.nextLine();
System.out.println(getPostfixValue(convert2Postfix(expression)));
}//主程序
}
程序說明
將中綴表達式轉換為后綴表達式后進行計算,以下引自百度百科
a. 若為 '(',入棧;
b. 若為 ')',則依次把棧中的的運算符加入后綴表達式中,直到出現'(',從棧中刪除'(' ;
c. 若為 除括號外的其他運算符, 當其優先級高於除'('以外的棧頂運算符時,直接入棧。否則從棧頂開始,依次彈出比當前處理的運算符優先級高和優先級相等的運算符,直到一個比它優先級低的或者遇到了一個左括號為止。
·當掃描的中綴表達式結束時,棧中的的所有運算符出棧;
轉換成后綴表達式再進行相應計算,詳見注釋