国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發(fā) > Java > 正文

java代碼執(zhí)行字符串中的邏輯運(yùn)算方法

2024-07-14 08:41:38
字體:
供稿:網(wǎng)友

方式一

public class Test{ public static void main(String[] args) throws Exception {   String str = "(a or b) and c";   str = str.replaceAll("or", "||");   str = str.replaceAll("and", "&&");   System.out.println(str);   ScriptEngineManager manager = new ScriptEngineManager();   ScriptEngine engine = manager.getEngineByName("js");   engine.put("a",true);   engine.put("b",false);   engine.put("c",true);     Object result = engine.eval_r(str);   System.out.println("結(jié)果類型:" + result.getClass().getName() + ",計(jì)算結(jié)果:" + result);  }}

這種方式使用js的方式進(jìn)行運(yùn)算,使用較簡單,但是當(dāng)運(yùn)算double類型的四則運(yùn)算時(shí)結(jié)果會出現(xiàn)循環(huán)小數(shù),運(yùn)算結(jié)果會出現(xiàn)問題.

方式二(能夠保證四則運(yùn)算精度):

/** * @Project:  BizRule   * @File:   org.coffeesweet.util.MathExpress.java * @Author:  coffeesweet * @Date:   2011-3-28 * @Description: 2011 coffeesweet Inc. All rights reserved. */package org.coffeesweet.util;import java.math.BigDecimal;import java.math.MathContext;import java.math.RoundingMode;import java.util.ArrayList;import java.util.LinkedList;import java.util.List;import java.util.StringTokenizer;import java.util.regex.Matcher;import java.util.regex.Pattern;/** * @author coffeesweet * +,-,*,/四則運(yùn)算的表達(dá)式逆波蘭解析計(jì)算類,精確計(jì)算,應(yīng)用BigDecimal類處理 * 支持負(fù)數(shù),但規(guī)范除整個(gè)表達(dá)式第一個(gè)數(shù)為負(fù)數(shù)時(shí)可以不出現(xiàn)在'('后,其它表達(dá)式中間任何位置的 * 負(fù)數(shù)必須出現(xiàn)在'('后,即:用括號括起來。比如:-3+(-2+1)*10或-3+((-2)+1)*10或(-3)+(-2+1)*10或(-3)+((-2)+1)*10 */public class MathExpress { /**  * +  */ private final static String OP1 = "+"; /**  * -  */ private final static String OP2 = "-"; /**  * *  */ private final static String OP3 = "*"; /**  * /  */ private final static String OP4 = "/"; /**  * ^  */// private final static String OP5 = "^"; /**  * %  */// private final static String OP6 = "%"; /**  * (  */ private final static String OPSTART = "("; /**  * )  */ private final static String OPEND = ")"; /**  * !用來替代負(fù)數(shù)前面的'-'  */// private final static String NEGATIVESING = "!"; /**  * !用來替代負(fù)數(shù)前面的'+'  */// private final static String PLUSSING = "@"; /**  * '#'用來代表運(yùn)算級別最低的特殊字符  */// private final static String LOWESTSING = "#"; //最原始的四則運(yùn)算式 private String expBase; //經(jīng)過初始化處理后的四則運(yùn)算式 private String expInited; //精度 private int precision=10; //取舍模式 private RoundingMode roundingMode=RoundingMode.HALF_UP; //精度上下文 private MathContext mc; //四則運(yùn)算解析 private List<String> expList = new ArrayList<String>(); //存放逆波蘭表達(dá)式 private List<String> rpnList = new ArrayList<String>(); public MathExpress(){ } public MathExpress(String expBase) {  init(expBase,this.precision,this.roundingMode); } public MathExpress(String expBase,int precision,RoundingMode roundingMode){  init(expBase,precision,roundingMode); } public void init(String expBase,int precision,RoundingMode roundingMode){  this.expBase = expBase;  this.precision = precision;  this.roundingMode = roundingMode;  this.mc = new MathContext(precision,roundingMode);  this.expInited = initExpress(expBase);  StringTokenizer st = new StringTokenizer(this.expInited,"+-*/^%()",true);  while(st.hasMoreElements()){   this.expList.add(st.nextElement().toString().trim());  }  this.rpnList = initRPN(this.expList); } /**  * @return the expBase  */ public String getExpBase() {  return expBase; } /**  * @param expBase the expBase to set  */ public void setExpBase(String expBase) {  this.expBase = expBase; } /**  * @return the expInited  */ public String getExpInited() {  return expInited; } /**  * @param expInited the expInited to set  */ public void setExpInited(String expInited) {  this.expInited = expInited; } /**  * @return the precision  */ public int getPrecision() {  return precision; } /**  * @param precision the precision to set  */ public void setPrecision(int precision) {  this.precision = precision; } /**  * @return the roundingMode  */ public RoundingMode getRoundingMode() {  return roundingMode; } /**  * @param roundingMode the roundingMode to set  */ public void setRoundingMode(RoundingMode roundingMode) {  this.roundingMode = roundingMode; } /**  * @return the expList  */ public List<String> getExpList() {  return expList; } /**  * @param expList the expList to set  */ public void setExpList(List<String> expList) {  this.expList = expList; } /**  * @return the rpnList  */ public List<String> getRpnList() {  return rpnList; } /**  * @param rpnList the rpnList to set  */ public void setRpnList(List<String> rpnList) {  this.rpnList = rpnList; } /**  * @return the mc  */ public MathContext getMc() {  return mc; } /**  * @param mc the mc to set  */ public void setMc(MathContext mc) {  this.mc = mc; } /**  * 去除空白字符和在負(fù)號'-'前加'0',便于后面的StringTokenizer  * @param exp  * @return  */ private static String initExpress(String exp){  String reStr = null;  reStr = exp.replaceAll("//s", "");  if(reStr.startsWith("-")){   reStr = "0"+reStr;  }  reStr = reStr.replaceAll("//(//-", "(0-");  return reStr; } /**  * 是否是整數(shù)或是浮點(diǎn)數(shù),但默認(rèn)-05.15這種也認(rèn)為是正確的格式  * @param str  * @return  */ private boolean isNumber(String str){  Pattern p = Pattern.compile("^(-?//d+)(//.//d+)?$");  Matcher m = p.matcher(str);  boolean isNumber = m.matches();  return isNumber; } /**  * 設(shè)置優(yōu)先級順序()設(shè)置與否無所謂  * @param sign  * @return  */ private int precedence(String str){  char sign = str.charAt(0);  switch(sign){   case '+':   case '-':    return 1;   case '*':   case '/':    return 2;   case '^':   case '%':    return 3;   case '(':   case ')'://   case '#':   default:    return 0;  } } /**  * 轉(zhuǎn)變?yōu)槟娌ㄌm表達(dá)式  * @param strList  * @return  */ public List<String> initRPN(List<String> strList){  List<String> returnList = new ArrayList<String>();  //用來存放操作符的棧  Stack stack = new Stack();//  stack.push(LOWESTSING);  int length = strList.size();  for(int i=0;i<length;i++ ){   String str = strList.get(i);   if(isNumber(str)){    returnList.add(str);   }else{    if(str.equals(OPSTART)){     //'('直接入棧     stack.push(str);    }else if(str.equals(OPEND)){     //')'     //進(jìn)行出棧操作,直到棧為空或者遇到第一個(gè)左括號      while (!stack.isEmpty()) {       //將棧頂字符串做出棧操作       String tempC = stack.pop();       if (!tempC.equals(OPSTART)) {        //如果不是左括號,則將字符串直接放到逆波蘭鏈表的最后        returnList.add(tempC);       }else{        //如果是左括號,退出循環(huán)操作        break;       }      }     }else{     if (stack.isEmpty()) {      //如果棧內(nèi)為空       //將當(dāng)前字符串直接壓棧       stack.push(str);      }else{      //棧不空,比較運(yùn)算符優(yōu)先級順序      if(precedence(stack.top())>=precedence(str)){       //如果棧頂元素優(yōu)先級大于當(dāng)前元素優(yōu)先級則       while(!stack.isEmpty() && precedence(stack.top())>=precedence(str)){        returnList.add(stack.pop());       }      }      stack.push(str);     }    }   }  }  //如果棧不為空,則將棧中所有元素出棧放到逆波蘭鏈表的最后   while (!stack.isEmpty()) {   returnList.add(stack.pop());  }  return returnList; } /**  * 計(jì)算逆波蘭表達(dá)式  * @param rpnList  * @return  */ public String caculate(List<String> rpnList){  Stack numberStack = new Stack();   int length=rpnList.size();   for(int i=0;i<length;i++){    String temp=rpnList.get(i);    if(isNumber(temp)){     numberStack.push(temp);    }else{     BigDecimal tempNumber1 = new BigDecimal(numberStack.pop(),this.mc);    BigDecimal tempNumber2 = new BigDecimal(numberStack.pop(),this.mc);    BigDecimal tempNumber = new BigDecimal("0",this.mc);    if(temp.equals(OP1)){      tempNumber=tempNumber2.add(tempNumber1);     }else if(temp.equals(OP2)){      tempNumber=tempNumber2.subtract(tempNumber1);     }else if(temp.equals(OP3)){      tempNumber=tempNumber2.multiply(tempNumber1);     }else if(temp.equals(OP4)){      tempNumber=tempNumber2.divide(tempNumber1,        precision,        roundingMode);     }     numberStack.push(tempNumber.toString());    }   }   return numberStack.pop(); } /**  * 按照類的缺省參數(shù)進(jìn)行計(jì)算  * @return  */ public String caculate(){  return caculate(this.rpnList); } /**  * 數(shù)字條件表達(dá)式精確比較  * eg: "3.0>2" "1<5" "1==5" "1!=5" "(1.0+2)>3" "((-0.9+3)>=2. 1)"  * 不支持&&,||等連接符  * @param str  * @return  */ public static boolean compareTo(String strParm){  boolean reBoolean = false;  boolean isParentheses = false;//標(biāo)記是否有()括上整個(gè)字符串  String str = initExpress(strParm);  Pattern p = Pattern.compile("^//([//s//S]*//)$");  Matcher m = p.matcher(str);  isParentheses = m.matches();  if(-1==str.indexOf(">=")&&-1==str.indexOf("<=")&&-1==str.indexOf("==")&&-1==str.indexOf("!=")){   if(-1==str.indexOf(">")&&-1==str.indexOf("<"))   throw new IllegalArgumentException("異常:條件表達(dá)式不正確!");  }  if(-1 != str.indexOf(">=")){   String[] strTemps = str.split(">=");   if(isParentheses){    strTemps[0] = strTemps[0] + ")";    strTemps[1] = "(" + strTemps[1];   }   int r = new BigDecimal((new MathExpress(strTemps[0]).caculate())).compareTo(new BigDecimal((new MathExpress(strTemps[1]).caculate())));   if( -1 == r ){    reBoolean = false;   }else{    reBoolean = true;   }  }else if(-1 != str.indexOf("<=")){   String[] strTemps = str.split("<=");   if(isParentheses){    strTemps[0] = strTemps[0] + ")";    strTemps[1] = "(" + strTemps[1];   }   int r = new BigDecimal((new MathExpress(strTemps[0]).caculate())).compareTo(new BigDecimal((new MathExpress(strTemps[1]).caculate())));   if( 1 == r ){    reBoolean = false;   }else{    reBoolean = true;   }  }else if(-1 != str.indexOf("==")){   String[] strTemps = str.split("==");   if(isParentheses){    strTemps[0] = strTemps[0] + ")";    strTemps[1] = "(" + strTemps[1];   }   int r = new BigDecimal((new MathExpress(strTemps[0]).caculate())).compareTo(new BigDecimal((new MathExpress(strTemps[1]).caculate())));   if( 0 == r ){    reBoolean = true;   }else{    reBoolean = false;   }  }else if(-1 != str.indexOf("!=")){   String[] strTemps = str.split("!=");   if(isParentheses){    strTemps[0] = strTemps[0] + ")";    strTemps[1] = "(" + strTemps[1];   }   int r = new BigDecimal((new MathExpress(strTemps[0]).caculate())).compareTo(new BigDecimal((new MathExpress(strTemps[1]).caculate())));   if( 0 != r ){    reBoolean = true;   }else{    reBoolean = false;   }  }else if((-1 != str.indexOf(">")) && (-1 == str.indexOf("="))){   String[] strTemps = str.split(">");   if(isParentheses){    strTemps[0] = strTemps[0] + ")";    strTemps[1] = "(" + strTemps[1];   }   int r = new BigDecimal((new MathExpress(strTemps[0]).caculate())).compareTo(new BigDecimal((new MathExpress(strTemps[1]).caculate())));   if( 1 == r ){    reBoolean = true;   }else{    reBoolean = false;   }  }else if((-1 != str.indexOf("<")) && (-1 == str.indexOf("="))){   String[] strTemps = str.split("<");   if(isParentheses){    strTemps[0] = strTemps[0] + ")";    strTemps[1] = "(" + strTemps[1];   }   int r = new BigDecimal((new MathExpress(strTemps[0]).caculate())).compareTo(new BigDecimal((new MathExpress(strTemps[1]).caculate())));   if( -1 == r ){    reBoolean = true;   }else{    reBoolean = false;   }  }  return reBoolean; } public static void main(String...args){//  MathExpress me = new MathExpress("-(-0.5+0.1)*10+2",10,RoundingMode.HALF_UP);//  System.out.println(me.getExpList());//  List<String> tempList = me.initRPN(me.getExpList());//  System.out.println(tempList);//  String resultStr = me.caculate(tempList);//  System.out.println(resultStr);  MathExpress me = new MathExpress("-(-1.5000000003+0.1)*10+2");  String resultStr = me.caculate();  BigDecimal bd = new BigDecimal(resultStr);  BigDecimal bd2 = bd.setScale(2, RoundingMode.HALF_UP);  System.out.println(me.caculate());  System.out.println(bd.toString());  System.out.println(bd.scale());  System.out.println(bd2.toString());  System.out.println(bd2.scale());//  System.out.println("------------------------------------");//  Pattern p = Pattern.compile("^//([//s//S]*//)$");//匹配類似以'('開頭')'結(jié)尾的字符串//  Matcher m = p.matcher("(2. 0>2.22)");//  System.out.println(m.matches());  boolean reBoolean = MathExpress.compareTo("((-8.0+3)>=2. 1)");  System.out.println(reBoolean); } /**  * 棧  */ private class Stack {  LinkedList<String> stackList = new LinkedList<String>();  public Stack() {  }  /**   * 入棧   * @param expression   */  public void push(String expression) {   stackList.addLast(expression);  }  /**   * 出棧   * @return   */  public String pop() {   return stackList.removeLast();  }  /**   * 棧頂元素   * @return   */  public String top() {   return stackList.getLast();  }  /**   * 棧是否為空   * @return   */  public boolean isEmpty() {   return stackList.isEmpty();  } }}

以上這篇java代碼執(zhí)行字符串中的邏輯運(yùn)算方法就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持VeVb武林網(wǎng)。


注:相關(guān)教程知識閱讀請移步到JAVA教程頻道。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 延川县| 偏关县| 边坝县| 泸水县| 霞浦县| 宜兴市| 海宁市| 伊川县| 陈巴尔虎旗| 香港| 韶关市| 庆云县| 伊金霍洛旗| 苍南县| 新丰县| 云阳县| 通道| 保康县| 工布江达县| 林甸县| 平潭县| 凤台县| 静海县| 辛集市| 仪陇县| 珠海市| 肇东市| 米脂县| 济宁市| 客服| 乌兰浩特市| 板桥市| 漠河县| 绍兴县| 百色市| 日喀则市| 城固县| 黄浦区| 耿马| 株洲市| 将乐县|