知道逆波蘭表達式是一個偶然的情況,在用js的時候偶然發現了js中的一個eval函數,數學的表達式它竟然能直接解析出結果。后面通過查詢才得知里面的核心是用的逆波蘭表達式的算法。后面網上找了一下java的逆波蘭表達式算法,沒有找到,后面就干脆自己寫一個,代碼可能有點low希望大牛們可以指導一下。這里引出的逆波蘭表達式通過java如何實現。代碼:
import java.util.LinkedList;
import java.util.List;
public class ReversePolishNotation {
// 定義一個運算符堆棧character
private static LinkedList characterList = new LinkedList<>();
// 定義一個操作符堆棧operator
private static LinkedList operatorList = new LinkedList<>();
// 定義一個StringBuffer的可變字符串
private static StringBuffer sb = new StringBuffer();
// 定義一個解析表達式結果的集合
private static LinkedList resultList = new LinkedList<>();
/** 逆波蘭表達式 以及表達式的運算*/
// 采用java語言對逆波蘭表達式進行解析
public static void analysis(String str) {
// 將表達式字符串進行解析
String[] strArr = str.trim().split("");
String strRes = "";
// System.out.println(strArr[0]+"--"+strArr[1]+"--"+strArr[2]);
// 如果是數字就入棧 如果是其他的就對棧頂的進行運算,具體的步驟
// 顯示入棧如果遇到運算符將棧頂的元素彈出進行運算得出的結果在入棧依次進行下去
// 如何解決運算符的優先級問題
// 根據元素進行操作
for (String s : strArr) {
if (s.equals("+") || s.equals("-")) {
operatorList.add(strRes.trim());
strRes = "";
// 表示是1級優先級 這個地方需要判斷運算符堆棧的堆頂運算符的優先級比較
// 如果比堆頂的優先級高則直接入堆
// 如果比堆頂的優先級低則將堆頂的運算符加入到操作符堆中
// 在繼續與下面的比較 如果還是小則重復上面的過程直到加入運算符堆中
priorityCompare(s);
} else if (s.equals("*") || s.equals("/")) {
operatorList.add(strRes.trim());
strRes = "";
priorityCompare(s);
} else if (s.equals("^") || s.equals("%")) {
operatorList.add(strRes.trim());
strRes = "";
priorityCompare(s);
} else if (s.equals("(")) {
operatorList.add(strRes.trim());
strRes = "";
characterList.add(s);
} else if (s.equals(")")) {
operatorList.add(strRes.trim());
strRes = "";
// 合并運算 一直到")"這個括號出現為止 將運算符的元素移動到操作符堆棧中
while (!characterList.peekLast().equals("(")) {
operatorList.add(characterList.pollLast());
}
characterList.removeLast();// 移除"("這個元素
} else {
// 表示是非運算符的處理
strRes = strRes + s;
}
}
if (strRes != "") {
operatorList.add(strRes);
strRes = "";
}
// 將operatorList里面的空元素剔除
while(operatorList.contains("")){
operatorList.remove("");
}
// 循環走過之后應該將運算符中的元素依次移除到操作符堆棧中
String strTmp = "";
while ((strTmp = characterList.pollLast()) != null) {
operatorList.add(strTmp);
}
analysisEquals(operatorList);
}
/** 運算符堆的優先級比較 */
public static void priorityCompare(String s) {
if (transformPriority(s) > transformPriority(characterList.peekLast())) {
// 表示優先級高 加入到運算符堆中
characterList.add(s);
} else {
// 將運算符堆的堆頂元素加入到操作符堆中并繼續判斷
String str = characterList.pollLast();
if (str != null) {
operatorList.add(str);
priorityCompare(s);
} else {
priorityCompare(s);
}
}
}
/** 優先級的轉換 */
public static int transformPriority(String s) {
if (s != null) {
if (s.equals("+") || s.equals("-")) {
return 1;
} else if (s.equals("*") || s.equals("/")) {
return 2;
} else if (s.equals("^") || s.equals("%")) {
return 3;
} else if (s.equals("(")) {
return 0;
} else {
return 0;
}
}
return 0;
}
/** 解析組合式 */
public static void analysisEquals( LinkedList operatorList ) {
// 解析表達式的基本準則 如果遇到運算符就將運算符的前面兩個元素和運算符彈出棧
for(String s : operatorList){
if(s.equals("+")||s.equals("-")||s.equals("*")
||s.equals("/")||s.equals("^")||s.equals("%")){
//將結果集的最后面的兩個元素彈出并進行運算
Double d1 = Double.parseDouble(resultList.pollLast());
Double d2 = Double.parseDouble(resultList.pollLast());
resultList.add(operation(d2, d1, s).toString());
}else{
resultList.add(s);
}
}
// 將他們進行運算之后在加入中間然后在依次進行運算
System.out.println(resultList);
}
/**逆波蘭表達式運算*/
public static Double operation(Double d1,Double d2,String s){
Double dou = 0.0;
switch(s){
case "+":
dou = d1+d2;
break;
case "-":
dou = d1-d2;
break;
case "*":
dou = d1*d2;
break;
case "/":
dou = d1/d2;
break;
case "^":
dou = Math.pow(d1, d2);
break;
case "%":
dou = d1%d2;
break;
}
return dou;
}
public static void main(String[] args) {
// String str = "a+b-(b-d)*e";//=> a,b,b,d,-,e,*,-,+
String str = "(100+(11-(90-18))*5)*0+205%5*0+2*22+((12-3)*5)*0";;
analysis(str);
// 打印一下操作符集合
System.out.println(operatorList);
}
}
最后編輯于 :
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。