采用JAVA對(duì)逆波蘭表達(dá)式解析淺見

? ? ? ? 本人剛剛學(xué)習(xí)java不就。知道逆波蘭表達(dá)式是一個(gè)偶然的情況,在用js的時(shí)候偶然發(fā)現(xiàn)了js中的一個(gè)eval函數(shù),數(shù)學(xué)的表達(dá)式它竟然能直接解析出結(jié)果。后面通過查詢才得知里面的核心是用的逆波蘭表達(dá)式的算法。后面網(wǎng)上找了一下java的逆波蘭表達(dá)式算法,沒有找到,后面就干脆自己寫一個(gè),代碼可能有點(diǎn)low希望大牛們可以指導(dǎo)一下。這里引出的逆波蘭表達(dá)式通過java如何實(shí)現(xiàn)。代碼:

import java.util.LinkedList;

import java.util.List;

public class ReversePolishNotation {

//?定義一個(gè)運(yùn)算符堆棧character

private static LinkedList characterList = new LinkedList<>();

//?定義一個(gè)操作符堆棧operator

private static LinkedList operatorList = new LinkedList<>();

//?定義一個(gè)StringBuffer的可變字符串

private static StringBuffer sb = new StringBuffer();

//?定義一個(gè)解析表達(dá)式結(jié)果的集合

private static LinkedList resultList = new LinkedList<>();

/**?逆波蘭表達(dá)式?以及表達(dá)式的運(yùn)算*/

//?采用java語言對(duì)逆波蘭表達(dá)式進(jìn)行解析

public static void analysis(String str)?{

//?將表達(dá)式字符串進(jìn)行解析

String[] strArr = str.trim().split("");

String strRes =?"";

// System.out.println(strArr[0]+"--"+strArr[1]+"--"+strArr[2]);

//?如果是數(shù)字就入棧?如果是其他的就對(duì)棧頂?shù)倪M(jìn)行運(yùn)算,具體的步驟

//?顯示入棧如果遇到運(yùn)算符將棧頂?shù)脑貜棾鲞M(jìn)行運(yùn)算得出的結(jié)果在入棧依次進(jìn)行下去

//?如何解決運(yùn)算符的優(yōu)先級(jí)問題

//?根據(jù)元素進(jìn)行操作

for (String s : strArr)?{

if (s.equals("+")?|| s.equals("-"))?{

operatorList.add(strRes.trim());

strRes =?"";

//?表示是1級(jí)優(yōu)先級(jí)?這個(gè)地方需要判斷運(yùn)算符堆棧的堆頂運(yùn)算符的優(yōu)先級(jí)比較

//?如果比堆頂?shù)膬?yōu)先級(jí)高則直接入堆

//?如果比堆頂?shù)膬?yōu)先級(jí)低則將堆頂?shù)倪\(yùn)算符加入到操作符堆中

//?在繼續(xù)與下面的比較?如果還是小則重復(fù)上面的過程直到加入運(yùn)算符堆中

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?=?"";

//?合并運(yùn)算?一直到")"這個(gè)括號(hào)出現(xiàn)為止?將運(yùn)算符的元素移動(dòng)到操作符堆棧中

while?(!characterList.peekLast().equals("("))?{

operatorList.add(characterList.pollLast());

}

characterList.removeLast();//?移除"("這個(gè)元素

} else {

//?表示是非運(yùn)算符的處理

strRes?= strRes + s;

}

}

if (strRes?!=?"")?{

operatorList.add(strRes);

strRes?=?"";

}

//?將operatorList里面的空元素剔除

while(operatorList.contains("")){

operatorList.remove("");

}

//?循環(huán)走過之后應(yīng)該將運(yùn)算符中的元素依次移除到操作符堆棧中

String strTmp =?"";

while?((strTmp?= characterList.pollLast())?!= null)?{

operatorList.add(strTmp);

}

analysisEquals(operatorList);

}

/**?運(yùn)算符堆的優(yōu)先級(jí)比較?*/

public static void priorityCompare(String s)?{

if (transformPriority(s)?> transformPriority(characterList.peekLast()))?{

//?表示優(yōu)先級(jí)高?加入到運(yùn)算符堆中

characterList.add(s);

} else {

//?將運(yùn)算符堆的堆頂元素加入到操作符堆中并繼續(xù)判斷

String str = characterList.pollLast();

if (str?!= null)?{

operatorList.add(str);

priorityCompare(s);

} else {

priorityCompare(s);

}

}

}

/**?優(yōu)先級(jí)的轉(zhuǎn)換?*/

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 )?{

//?解析表達(dá)式的基本準(zhǔn)則?如果遇到運(yùn)算符就將運(yùn)算符的前面兩個(gè)元素和運(yùn)算符彈出棧

for(String s : operatorList){

if(s.equals("+")||s.equals("-")||s.equals("*")

||s.equals("/")||s.equals("^")||s.equals("%")){

//將結(jié)果集的最后面的兩個(gè)元素彈出并進(jìn)行運(yùn)算

Double d1 = Double.parseDouble(resultList.pollLast());

Double d2 = Double.parseDouble(resultList.pollLast());

resultList.add(operation(d2, d1, s).toString());

}else{

resultList.add(s);

}

}

//?將他們進(jìn)行運(yùn)算之后在加入中間然后在依次進(jìn)行運(yùn)算

System.out.println(resultList);

}

/**逆波蘭表達(dá)式運(yùn)算*/

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);

}

}

? ? ? ?代碼可能有點(diǎn)亂?不喜歡不要噴?因?yàn)橐粫r(shí)興起,所以想保存一下這個(gè)就想到寫到博客里面了(*^__^*)?嘻嘻,里面有我的一些注解,如果有什么不好的地方?希望私信我。我改成過來。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,739評(píng)論 18 399
  • 一. Java基礎(chǔ)部分.................................................
    wy_sure閱讀 3,832評(píng)論 0 11
  • 從三月份找實(shí)習(xí)到現(xiàn)在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,340評(píng)論 11 349
  • 一、基本數(shù)據(jù)類型 注釋 單行注釋:// 區(qū)域注釋:/* */ 文檔注釋:/** */ 數(shù)值 對(duì)于byte類型而言...
    龍貓小爺閱讀 4,288評(píng)論 0 16
  • 小魚兒61閱讀 133評(píng)論 2 2