java中完成四則運算代碼。本站提示廣大學習愛好者:(java中完成四則運算代碼)文章只能為提供參考,不一定能成為您想要的結果。以下是java中完成四則運算代碼正文
代碼的思緒是經由過程正則斷定盤算每一個最小的盤算單位。以下是代碼:
import java.math.BigDecimal; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * 盤算器對象類 * @author shuqi * @date 2015-7-23 * @version since 1.0 */ public class CalculatorUtil { public static BigDecimal arithmetic(String exp){ if(!exp.matches("\\d+")){ String result = parseExp(exp).replaceAll("[\\[\\]]", ""); return new BigDecimal(result); }else{ return new BigDecimal(exp); } } /** * 最小計數單元 * */ private static String minExp="^((\\d+(\\.\\d+)?)|(\\[\\-\\d+(\\.\\d+)?\\]))[\\+\\-\\*\\/]((\\d+(\\.\\d+)?)|(\\[\\-\\d+(\\.\\d+)?\\]))$"; /** * 不帶括號的運算 */ private static String noParentheses="^[^\\(\\)]+$"; /** * 婚配乘法或許除法 */ private static String priorOperatorExp="(((\\d+(\\.\\d+)?)|(\\[\\-\\d+(\\.\\d+)?\\]))[\\*\\/]((\\d+(\\.\\d+)?)|(\\[\\-\\d+(\\.\\d+)?\\])))"; /** * 婚配加法和減法 */ private static String operatorExp="(((\\d+(\\.\\d+)?)|(\\[\\-\\d+(\\.\\d+)?\\]))[\\+\\-]((\\d+(\\.\\d+)?)|(\\[\\-\\d+(\\.\\d+)?\\])))"; /** * 婚配只帶一個括號的 */ private static String minParentheses="\\([^\\(\\)]+\\)"; /** * 解析盤算四則運算表達式,例:2+((3+4)*2-22)/2*3 * @param expression * @return */ private static String parseExp(String expression){ //辦法進入 先調換空格,在去除運算雙方的()號 expression=expression.replaceAll("\\s+", "").replaceAll("^\\(([^\\(\\)]+)\\)$", "$1"); //最小表達式盤算 if(expression.matches(minExp)){ String result=calculate(expression); return Double.parseDouble(result)>=0?result:"["+result+"]"; } //盤算不帶括號的四則運算 if(expression.matches(noParentheses)){ Pattern patt=Pattern.compile(priorOperatorExp); Matcher mat=patt.matcher(expression); if(mat.find()){ String tempMinExp=mat.group(); expression=expression.replaceFirst(priorOperatorExp, parseExp(tempMinExp)); }else{ patt=Pattern.compile(operatorExp); mat=patt.matcher(expression); if(mat.find()){ String tempMinExp=mat.group(); expression=expression.replaceFirst(operatorExp, parseExp(tempMinExp)); } } return parseExp(expression); } //盤算帶括號的四則運算 Pattern patt=Pattern.compile(minParentheses); Matcher mat=patt.matcher(expression); if(mat.find()){ String tempMinExp=mat.group(); expression=expression.replaceFirst(minParentheses, parseExp(tempMinExp)); } return parseExp(expression); } /** * 盤算最小單元四則運算表達式(兩個數字) * @param exp * @return */ private static String calculate(String exp){ exp=exp.replaceAll("[\\[\\]]", ""); String number[]=exp.replaceFirst("(\\d)[\\+\\-\\*\\/]", "$1,").split(","); BigDecimal number1=new BigDecimal(number[0]); BigDecimal number2=new BigDecimal(number[1]); BigDecimal result=null; String operator=exp.replaceFirst("^.*\\d([\\+\\-\\*\\/]).+$", "$1"); if("+".equals(operator)){ result=number1.add(number2); }else if("-".equals(operator)){ result=number1.subtract(number2); }else if("*".equals(operator)){ result=number1.multiply(number2); }else if("/".equals(operator)){ //第二個參數為精度,第三個為四色五入的形式 result=number1.divide(number2,5,BigDecimal.ROUND_CEILING); } return result!=null?result.toString():null; } }
代碼本來是一個博客,本來代碼沒有正文並且存在BUG,我略微修稿了一哈添加了正文。在這裡做個筆記,便利今後用
另為表現對原作者的敬意,附上原始代碼
/** * 四則運算表達式盤算 * @author penli * */ public class Arithmetic { public static void main(String args[]){ System.out.println(arithmetic("2.2+((3+4)*2-22)/2*3.2")); } public static double arithmetic(String exp){ String result = parseExp(exp).replaceAll("[\\[\\]]", ""); return Double.parseDouble(result); } /** * 解析盤算四則運算表達式,例:2+((3+4)*2-22)/2*3 * @param expression * @return */ public static String parseExp(String expression){ //String numberReg="^((?!0)\\d+(\\.\\d+(?<!0))?)|(0\\.\\d+(?<!0))$"; expression=expression.replaceAll("\\s+", "").replaceAll("^\\((.+)\\)$", "$1"); String checkExp="\\d"; String minExp="^((\\d+(\\.\\d+)?)|(\\[\\-\\d+(\\.\\d+)?\\]))[\\+\\-\\*\\/]((\\d+(\\.\\d+)?)|(\\[\\-\\d+(\\.\\d+)?\\]))$"; //最小表達式盤算 if(expression.matches(minExp)){ String result=calculate(expression); return Double.parseDouble(result)>=0?result:"["+result+"]"; } //盤算不帶括號的四則運算 String noParentheses="^[^\\(\\)]+$"; String priorOperatorExp="(((\\d+(\\.\\d+)?)|(\\[\\-\\d+(\\.\\d+)?\\]))[\\*\\/]((\\d+(\\.\\d+)?)|(\\[\\-\\d+(\\.\\d+)?\\])))"; String operatorExp="(((\\d+(\\.\\d+)?)|(\\[\\-\\d+(\\.\\d+)?\\]))[\\+\\-]((\\d+(\\.\\d+)?)|(\\[\\-\\d+(\\.\\d+)?\\])))"; if(expression.matches(noParentheses)){ Pattern patt=Pattern.compile(priorOperatorExp); Matcher mat=patt.matcher(expression); if(mat.find()){ String tempMinExp=mat.group(); expression=expression.replaceFirst(priorOperatorExp, parseExp(tempMinExp)); }else{ patt=Pattern.compile(operatorExp); mat=patt.matcher(expression); if(mat.find()){ String tempMinExp=mat.group(); expression=expression.replaceFirst(operatorExp, parseExp(tempMinExp)); } } return parseExp(expression); } //盤算帶括號的四則運算 String minParentheses="\\([^\\(\\)]+\\)"; Pattern patt=Pattern.compile(minParentheses); Matcher mat=patt.matcher(expression); if(mat.find()){ String tempMinExp=mat.group(); expression=expression.replaceFirst(minParentheses, parseExp(tempMinExp)); } return parseExp(expression); } /** * 盤算最小單元四則運算表達式(兩個數字) * @param exp * @return */ public static String calculate(String exp){ exp=exp.replaceAll("[\\[\\]]", ""); String number[]=exp.replaceFirst("(\\d)[\\+\\-\\*\\/]", "$1,").split(","); BigDecimal number1=new BigDecimal(number[0]); BigDecimal number2=new BigDecimal(number[1]); BigDecimal result=null; String operator=exp.replaceFirst("^.*\\d([\\+\\-\\*\\/]).+$", "$1"); if("+".equals(operator)){ result=number1.add(number2); }else if("-".equals(operator)){ result=number1.subtract(number2); }else if("*".equals(operator)){ result=number1.multiply(number2); }else if("/".equals(operator)){ result=number1.divide(number2); } return result!=null?result.toString():null; } }
最初給年夜家分享一個網友的完成辦法,小我感到也很不錯
import java.util.Stack; /** * 應用棧,停止四則運算的類 * 用兩個棧來完成算符優先,一個棧用來保留須要盤算的數據numStack,一個用來保留盤算優先符priStack * * 根本算法完成思緒為:用以後獲得的運算符與priStack棧頂運算符比擬優先級:若高於,則由於會先運算,放入棧頂; * 若等於,由於湧現在前面,所以會後盤算,所以棧頂元素出棧,掏出操作數運算; * 若小於,則同理,掏出棧頂元素運算,將成果入操作數棧。各個優先級'(' > '*' = '/' > '+' = '-' > ')' * */ public class Operate { private Stack<Character> priStack = new Stack<Character>();// 操作符棧 private Stack<Integer> numStack = new Stack<Integer>();;// 操作數棧 /** * 傳入須要解析的字符串,前往盤算成果(此處由於時光成績,省略正當性驗證) * @param str 須要停止技巧的表達式 * @return 盤算成果 */ public int caculate(String str) { // 1.斷定string傍邊有無不法字符 String temp;// 用光降時寄存讀取的字符 // 2.輪回開端解析字符串,當字符串解析完,且符號棧為空時,則盤算完成 StringBuffer tempNum = new StringBuffer();// 用光降時寄存數字字符串(當為多位數時) StringBuffer string = new StringBuffer().append(str);// 用來保留,進步效力 while (string.length() != 0) { temp = string.substring(0, 1); string.delete(0, 1); // 斷定temp,當temp為操作符時 if (!isNum(temp)) { // 1.此時的tempNum內即為須要操作的數,掏出數,壓棧,而且清空tempNum if (!"".equals(tempNum.toString())) { // 當表達式的第一個符號為括號 int num = Integer.parseInt(tempNum.toString()); numStack.push(num); tempNum.delete(0, tempNum.length()); } // 用以後獲得的運算符與棧頂運算符比擬優先級:若高於,則由於會先運算,放入棧頂;若等於,由於湧現在前面,所以會後盤算,所以棧頂元素出棧,掏出操作數運算; // 若小於,則同理,掏出棧頂元素運算,將成果入操作數棧。 // 斷定以後運算符與棧頂元素優先級,掏出元素,停止盤算(由於優先級能夠小於棧頂元素,還小於第二個元素等等,須要用輪回斷定) while (!compare(temp.charAt(0)) && (!priStack.empty())) { int a = (int) numStack.pop();// 第二個運算數 int b = (int) numStack.pop();// 第一個運算數 char ope = priStack.pop(); int result = 0;// 運算成果 switch (ope) { // 假如是加號或許減號,則 case '+': result = b + a; // 將操作成果放入操作數棧 numStack.push(result); break; case '-': result = b - a; // 將操作成果放入操作數棧 numStack.push(result); break; case '*': result = b * a; // 將操作成果放入操作數棧 numStack.push(result); break; case '/': result = b / a;// 將操作成果放入操作數棧 numStack.push(result); break; } } // 斷定以後運算符與棧頂元素優先級, 假如高,或許低於平,盤算完後,將以後操作符號,放入操作符棧 if (temp.charAt(0) != '#') { priStack.push(new Character(temp.charAt(0))); if (temp.charAt(0) == ')') {// 當棧頂為'(',而以後元素為')'時,則是括號內以算完,去失落括號 priStack.pop(); priStack.pop(); } } } else // 當為非操作符時(數字) tempNum = tempNum.append(temp);// 將讀到的這一名數接到以讀出的數後(當不是個位數的時刻) } return numStack.pop(); } /** * 斷定傳入的字符是否是0-9的數字 * * @param str * 傳入的字符串 * @return */ private boolean isNum(String temp) { return temp.matches("[0-9]"); } /** * 比擬以後操作符與棧頂元素操作符優先級,假如比棧頂元素優先級高,則前往true,不然前往false * * @param str 須要停止比擬的字符 * @return 比擬成果 true代表比棧頂元素優先級高,false代表比棧頂元素優先級低 */ private boolean compare(char str) { if (priStack.empty()) { // 當為空時,明顯 以後優先級最低,前往高 return true; } char last = (char) priStack.lastElement(); // 假如棧頂為'('明顯,優先級最低,')'弗成能為棧頂。 if (last == '(') { return true; } switch (str) { case '#': return false;// 停止符 case '(': // '('優先級最高,明顯前往true return true; case ')': // ')'優先級最低, return false; case '*': { // '*/'優先級只比'+-'高 if (last == '+' || last == '-') return true; else return false; } case '/': { if (last == '+' || last == '-') return true; else return false; } // '+-'為最低,一向前往false case '+': return false; case '-': return false; } return true; } public static void main(String args[]) { Operate operate = new Operate(); int t = operate.caculate("(3+4*(4*10-10/2)#"); System.out.println(t); } }