逆波兰计算器(含完整版)
                                                            生活随笔
收集整理的這篇文章主要介紹了
                                逆波兰计算器(含完整版)
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.                        
                                逆波蘭計(jì)算器
package com.hsy.stack;import java.util.ArrayList; import java.util.List; import java.util.Stack;/*** @author hsy*/ public class PolandCalculator {public static void main(String[] args) {//先定義一個(gè)逆波蘭表達(dá)式,并把其中的數(shù)據(jù)和符號(hào)用空格隔開(kāi)String expression = "3 4 + 5 * 6 -";//將這個(gè)字符串放入數(shù)組中,通過(guò)遍歷數(shù)組和stack數(shù)據(jù)結(jié)構(gòu)來(lái)完成計(jì)算List<String> list = getListString(expression);System.out.println(list);int res = calculate(list);System.out.println(res);}//把逆波蘭表達(dá)式放入數(shù)組的方法public static List<String> getListString(String expression) {//利用split方法將字符串分割,參數(shù)為空格,這樣原字符串中的空格就會(huì)被去掉String[] split = expression.split(" ");//創(chuàng)建一個(gè)類(lèi)型為字符串的數(shù)組List<String> list = new ArrayList<>();//遍歷字符串的每一個(gè)元素并放入數(shù)組中for (String s : split) {list.add(s);}return list;}//完成對(duì)逆波蘭表達(dá)式的運(yùn)算 // 1)從左至右掃描,將3和4壓入堆棧; // 2)遇到+運(yùn)算符,因此彈出4和3(4為棧頂元素,3為次頂元素),計(jì)算出3+4的值,得7,再將7入棧; // 3)將5入棧; // 4)接下來(lái)是×運(yùn)算符,因此彈出5和7,計(jì)算出7×5=35,將35入棧; // 5)將6入棧; // 6)最后是-運(yùn)算符,計(jì)算出35-6的值,即29,由此得出最終結(jié)果//計(jì)算方法public static int calculate(List<String> ls) {//創(chuàng)建一個(gè)棧Stack<String> stack = new Stack<>();// 遍歷 lsfor (String item : ls) {// 這里使用正則表達(dá)式來(lái)取出數(shù)if (item.matches("\\d+")) {// 這個(gè)正則表達(dá)式表示匹配的是多位數(shù)// 入棧stack.push(item);} else {// pop出兩個(gè)數(shù),并運(yùn)算, 再入棧int num2 = Integer.parseInt(stack.pop());int num1 = Integer.parseInt(stack.pop());int res = 0;if (item.equals("+")) {res = num1 + num2;} else if (item.equals("-")) {res = num1 - num2;} else if (item.equals("*")) {res = num1 * num2;} else if (item.equals("/")) {res = num1 / num2;} else {throw new RuntimeException("運(yùn)算符有誤!");}//把res 入棧stack.push("" + res);}}//最后留在stack中的數(shù)據(jù)是運(yùn)算結(jié)果return Integer.parseInt(stack.pop());}}完整版
package com.hsy.stack;import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Stack; import java.util.regex.Pattern;public class ReversePolishMultiCalculate {/*** 匹配 + - * / ( ) 運(yùn)算符*/static final String SYMBOL = "\\+|-|\\*|/|\\(|\\)";static final String LEFT = "(";static final String RIGHT = ")";static final String ADD = "+";static final String MINUS= "-";static final String TIMES = "*";static final String DIVISION = "/";/*** 加減 + -*/static final int LEVEL_01 = 1;/*** 乘除 * /*/static final int LEVEL_02 = 2;/*** 括號(hào)*/static final int LEVEL_HIGH = Integer.MAX_VALUE;static Stack<String> stack = new Stack<>();static List<String> data = Collections.synchronizedList(new ArrayList<String>());/*** 去除所有空白符* @param s* @return*/public static String replaceAllBlank(String s ){// \\s+ 匹配任何空白字符,包括空格、制表符、換頁(yè)符等等, 等價(jià)于[ \f\n\r\t\v]return s.replaceAll("\\s+","");}/*** 判斷是不是數(shù)字 int double long float* @param s* @return*/public static boolean isNumber(String s){Pattern pattern = Pattern.compile("^[-\\+]?[.\\d]*$");return pattern.matcher(s).matches();}/*** 判斷是不是運(yùn)算符* @param s* @return*/public static boolean isSymbol(String s){return s.matches(SYMBOL);}/*** 匹配運(yùn)算等級(jí)* @param s* @return*/public static int calcLevel(String s){if("+".equals(s) || "-".equals(s)){return LEVEL_01;} else if("*".equals(s) || "/".equals(s)){return LEVEL_02;}return LEVEL_HIGH;}/*** 匹配* @param s* @throws Exception*/public static List<String> doMatch (String s) throws Exception{if(s == null || "".equals(s.trim())) throw new RuntimeException("data is empty");if(!isNumber(s.charAt(0)+"")) throw new RuntimeException("data illeagle,start not with a number");s = replaceAllBlank(s);String each;int start = 0;for (int i = 0; i < s.length(); i++) {if(isSymbol(s.charAt(i)+"")){each = s.charAt(i)+"";//棧為空,(操作符,或者 操作符優(yōu)先級(jí)大于棧頂優(yōu)先級(jí) && 操作符優(yōu)先級(jí)不是( )的優(yōu)先級(jí) 及是 ) 不能直接入棧if(stack.isEmpty() || LEFT.equals(each)|| ((calcLevel(each) > calcLevel(stack.peek())) && calcLevel(each) < LEVEL_HIGH)){stack.push(each);}else if( !stack.isEmpty() && calcLevel(each) <= calcLevel(stack.peek())){//棧非空,操作符優(yōu)先級(jí)小于等于棧頂優(yōu)先級(jí)時(shí)出棧入列,直到棧為空,或者遇到了(,最后操作符入棧while (!stack.isEmpty() && calcLevel(each) <= calcLevel(stack.peek()) ){if(calcLevel(stack.peek()) == LEVEL_HIGH){break;}data.add(stack.pop());}stack.push(each);}else if(RIGHT.equals(each)){// ) 操作符,依次出棧入列直到空棧或者遇到了第一個(gè))操作符,此時(shí))出棧while (!stack.isEmpty() && LEVEL_HIGH >= calcLevel(stack.peek())){if(LEVEL_HIGH == calcLevel(stack.peek())){stack.pop();break;}data.add(stack.pop());}}start = i ; //前一個(gè)運(yùn)算符的位置}else if( i == s.length()-1 || isSymbol(s.charAt(i+1)+"") ){each = start == 0 ? s.substring(start,i+1) : s.substring(start+1,i+1);if(isNumber(each)) {data.add(each);continue;}throw new RuntimeException("data not match number");}}//如果棧里還有元素,此時(shí)元素需要依次出棧入列,可以想象棧里剩下棧頂為/,棧底為+,應(yīng)該依次出棧入列,可以直接翻轉(zhuǎn)整個(gè)stack 添加到隊(duì)列Collections.reverse(stack);data.addAll(new ArrayList<>(stack));System.out.println(data);return data;}/*** 算出結(jié)果* @param list* @return*/public static Double doCalc(List<String> list){Double d = 0d;if(list == null || list.isEmpty()){return null;}if (list.size() == 1){System.out.println(list);d = Double.valueOf(list.get(0));return d;}ArrayList<String> list1 = new ArrayList<>();for (int i = 0; i < list.size(); i++) {list1.add(list.get(i));if(isSymbol(list.get(i))){Double d1 = doTheMath(list.get(i - 2), list.get(i - 1), list.get(i));list1.remove(i);list1.remove(i-1);list1.set(i-2,d1+"");list1.addAll(list.subList(i+1,list.size()));break;}}doCalc(list1);return d;}/*** 運(yùn)算* @param s1* @param s2* @param symbol* @return*/public static Double doTheMath(String s1,String s2,String symbol){Double result ;switch (symbol){case ADD : result = Double.valueOf(s1) + Double.valueOf(s2); break;case MINUS : result = Double.valueOf(s1) - Double.valueOf(s2); break;case TIMES : result = Double.valueOf(s1) * Double.valueOf(s2); break;case DIVISION : result = Double.valueOf(s1) / Double.valueOf(s2); break;default : result = null;}return result;}public static void main(String[] args) {//String math = "9+(3-1)*3+10/2";String math = "12.8 + (2 - 3.55)*4+10/5.0";try {doCalc(doMatch(math));} catch (Exception e) {e.printStackTrace();}}}總結(jié)
以上是生活随笔為你收集整理的逆波兰计算器(含完整版)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
 
                            
                        - 上一篇: html5绘制好看的时钟,利用纯html
- 下一篇: win10更新之后搜狗输入法、QQ拼音输
