亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

 更新時間:2018年07月18日 09:10:33   作者:Zzooper  
今天小編就為大家分享一篇java代碼執(zhí)行字符串中的邏輯運算方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧

方式一

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() + ",計算結(jié)果:" + result);
  }
}

這種方式使用js的方式進行運算,使用較簡單,但是當運算double類型的四則運算時結(jié)果會出現(xiàn)循環(huán)小數(shù),運算結(jié)果會出現(xià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īng)用BigDecimal類處理
 * 支持負數(shù),但規(guī)范除整個表達式第一個數(shù)為負數(shù)時可以不出現(xiàn)在'('后,其它表達式中間任何位置的
 * 負數(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 = ")";
 /**
  * !用來替代負數(shù)前面的'-'
  */
// private final static String NEGATIVESING = "!";
 /**
  * !用來替代負數(shù)前面的'+'
  */
// private final static String PLUSSING = "@";
 /**
  * '#'用來代表運算級別最低的特殊字符
  */
// private final static String LOWESTSING = "#";
 //最原始的四則運算式
 private String expBase;
 //經(jīng)過初始化處理后的四則運算式
 private String expInited;
 //精度
 private int precision=10;
 //取舍模式
 private RoundingMode roundingMode=RoundingMode.HALF_UP;
 //精度上下文
 private MathContext mc;
 //四則運算解析
 private List<String> expList = new ArrayList<String>();
 //存放逆波蘭表達式
 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;
 }
 /**
  * 去除空白字符和在負號'-'前加'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ù)或是浮點數(shù),但默認-05.15這種也認為是正確的格式
  * @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表達式
  * @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)){
     //')'
     //進行出棧操作,直到棧為空或者遇到第一個左括號 
     while (!stack.isEmpty()) { 
      //將棧頂字符串做出棧操作 
      String tempC = stack.pop(); 
      if (!tempC.equals(OPSTART)) { 
       //如果不是左括號,則將字符串直接放到逆波蘭鏈表的最后 
       returnList.add(tempC); 
      }else{ 
       //如果是左括號,退出循環(huán)操作 
       break; 
      } 
     } 
    }else{
     if (stack.isEmpty()) {
      //如果棧內(nèi)為空 
      //將當前字符串直接壓棧 
      stack.push(str); 
     }else{
      //棧不空,比較運算符優(yōu)先級順序
      if(precedence(stack.top())>=precedence(str)){
       //如果棧頂元素優(yōu)先級大于當前元素優(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;
 }
 /**
  * 計算逆波蘭表達式
  * @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ù)進行計算
  * @return
  */
 public String caculate(){
  return caculate(this.rpnList);
 }
 /**
  * 數(shù)字條件表達式精確比較
  * 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;//標記是否有()括上整個字符串
  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("異常:條件表達式不正確!");
  }
  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í)行字符串中的邏輯運算方法就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 基于Java實現(xiàn)一個復(fù)雜關(guān)系表達式過濾器

    基于Java實現(xiàn)一個復(fù)雜關(guān)系表達式過濾器

    這篇文章主要為大家詳細介紹了如何基于Java實現(xiàn)一個復(fù)雜關(guān)系表達式過濾器。文中的示例代碼講解詳細,感興趣的小伙伴可以了解一下
    2022-07-07
  • 詳解Java?ReentrantLock可重入,可打斷,鎖超時的實現(xiàn)原理

    詳解Java?ReentrantLock可重入,可打斷,鎖超時的實現(xiàn)原理

    前面講解了ReentrantLock加鎖和解鎖的原理實現(xiàn),但是沒有闡述它的可重入、可打斷以及超時獲取鎖失敗的原理,本文就重點講解這三種情況,需要的可以了解一下
    2022-10-10
  • JAVA并發(fā)圖解

    JAVA并發(fā)圖解

    這篇文章主要介紹了JAVA的并發(fā),文中圖解非常細致,代碼幫助大家更好的理解和學習,感興趣的朋友可以了解下
    2021-09-09
  • Java中Elasticsearch 實現(xiàn)分頁方式(三種方式)

    Java中Elasticsearch 實現(xiàn)分頁方式(三種方式)

    Elasticsearch是用Java語言開發(fā)的,并作為Apache許可條款下的開放源碼發(fā)布,是一種流行的企業(yè)級搜索引擎,這篇文章主要介紹了Elasticsearch實現(xiàn)分頁的3種方式,需要的朋友可以參考下
    2022-07-07
  • java集合框架線程同步代碼詳解

    java集合框架線程同步代碼詳解

    這篇文章主要介紹了java集合框架線程同步代碼詳解,具有一定借鑒價值,需要的朋友可以參考下。
    2017-12-12
  • Java排序算法總結(jié)之冒泡排序

    Java排序算法總結(jié)之冒泡排序

    這篇文章主要介紹了Java排序算法總結(jié)之冒泡排序,較為詳細的分析了冒泡排序的原理與java實現(xiàn)技巧,需要的朋友可以參考下
    2015-05-05
  • 詳解如何配置springboot跳轉(zhuǎn)html頁面

    詳解如何配置springboot跳轉(zhuǎn)html頁面

    這篇文章主要介紹了詳解如何配置springboot跳轉(zhuǎn)html頁面,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-09-09
  • Java super關(guān)鍵字的用法詳解

    Java super關(guān)鍵字的用法詳解

    在JAVA類中使用super來引用父類的成分,用this來引用當前對象,如果一個類從另外一個類繼承,我們new這個子類的實例對象的時候,這個子類對象里面會有一個父類對象。怎么引用里面的父類對象呢?用super來引用,this指當前對象的引用,super是當前對象里面的父對象的引用
    2021-11-11
  • java創(chuàng)建excel示例(jxl使用方法)

    java創(chuàng)建excel示例(jxl使用方法)

    Java Excel是一開放源碼項目,通過它Java開發(fā)人員可以讀取Excel文件的內(nèi)容、創(chuàng)建新的Excel文件、更新 已經(jīng)存在的Excel文件。下面是使用方法,包括去掉網(wǎng)格線、字體設(shè)置、單元格設(shè)置、對齊方式等設(shè)置
    2014-03-03
  • Java toString方法重寫工具之ToStringBuilder案例詳解

    Java toString方法重寫工具之ToStringBuilder案例詳解

    這篇文章主要介紹了Java toString方法重寫工具之ToStringBuilder案例詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-08-08

最新評論