栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java实现四则混合运算代码示例

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java实现四则混合运算代码示例

使用栈来实现,可以处理运算优先级。

使用自然四则运算表达式即可,如:4+(3*(3-1)+2)/2。无需把表达式先转换为逆波兰等形式。

package com.joshua.cal; 
import java.util.Collections; 
import java.util.HashMap; 
import java.util.HashSet; 
import java.util.linkedList; 
import java.util.List; 
import java.util.Map; 
import java.util.Set; 
import java.util.Stack; 
public class Calculator { 
  private final Stack numStack = new Stack(); 
  private final Stack opStack = new Stack(); 
  private char currentOperator; 
  private char opStackTop; 
  private int i; 
  private String expression; 
  @SuppressWarnings("rawtypes") 
  public void exec(String expression) { 
    try { 
      clean(); 
      if (expression == null || expression.isEmpty()) { 
 throw new IllegalArgumentException("Blank expression!"); 
      } 
      this.expression = expression; 
      opStack.push(TERMINATE_TOKENS.START_END_MARK); 
      List tokens = TOKENIZER.exec(expression 
   + TERMINATE_TOKENS.START_END_MARK); 
      for (; i < tokens.size(); i++) { 
 final Object token = tokens.get(i); 
 if (token instanceof Double) { 
   processOperand((double) token); 
 } else { 
   processOperator((char) token); 
 } 
      } 
    } catch (Throwable e) { 
      System.err.println(String.format( 
   "Incorret expression: %snError: %s", expression, 
   e.getMessage())); 
    } 
  } 
  private void processOperand(final double operand) { 
    numStack.push(operand); 
  } 
  private void processOperator(final char currentOperator) { 
    this.currentOperator = currentOperator; 
    this.opStackTop = opStack.peek(); 
    char calMode = CALCULATE_MODE.getRule(currentOperator, opStackTop); 
    switch (calMode) { 
    case '>': 
      processStackHigerPriorityOperator(); 
      break; 
    case '<': 
      processStackLowerPriorityOperator(); 
      break; 
    case '=': 
      processStackEqualPriorityOperator(); 
      break; 
    default: 
      break; 
    } 
  } 
  private void processStackLowerPriorityOperator() { 
    opStack.push(currentOperator); 
  } 
  private void processStackHigerPriorityOperator() { 
    numStack.push(CALCULATE.exec(opStack.pop(), numStack.pop(), 
 numStack.pop())); 
    --i; // pointer back to the previous operator. 
  } 
  private void processStackEqualPriorityOperator() { 
    if (TERMINATE_TOKENS.START_END_MARK == currentOperator) { 
      System.out.println(expression + " = " + numStack.peek()); 
    } else if (')' == currentOperator) { 
      opStack.pop(); 
    } 
  } 
  public void clean() { 
    numStack.clear(); 
    opStack.clear(); 
    i = 0; 
  } 
  public static void main(String[] args) { 
    Calculator cal = new Calculator(); 
    cal.exec("4+(3*(3-1)+2)/2"); // = 8 
    cal.exec("4 + (-3 * ( 3 - 1 ) + 2)"); // = 0 
    cal.exec("4 +-/ (-3 * ( 3 - 1 ) + 2)"); // incorrect expression! 
    cal.exec("4.5+(3.2+3)/2"); // = 7.6 
    cal.exec("4.5+(3.2:3)/2"); // incorrect expression! 
    cal.exec("-4.5+(3.2-3)/2"); // = -4.4 
  } 
} 
enum CALCULATE { 
  INSTANCE; 
  public static double exec(final char operator, final double right, 
      final double left) { 
    switch (operator) { 
    case '+': 
      return left + right; 
    case '-': 
      return left - right; 
    case '*': 
      return left * right; 
    case '/': 
      return left / right; 
    default: 
      throw new IllegalArgumentException("Unsupported operator: " 
   + operator); 
    } 
  } 
} 
enum TERMINATE_TOKENS { 
  INSTANCE; 
  public static final char START_END_MARK = '#'; 
  private static final Map TOKENs = new HashMap(); 
  static { 
    // token, token id 
    TOKENs.put('+', 0); 
    TOKENs.put('-', 1); 
    TOKENs.put('*', 2); 
    TOKENs.put('/', 3); 
    TOKENs.put('(', 4); 
    TOKENs.put(')', 5); 
    TOKENs.put(START_END_MARK, 6); 
  } 
  private static Set NEGATIVE_NUM_SENSITIVE = new HashSet(); 
  public static synchronized Set getNegativeNumSensitiveToken() { 
    if (NEGATIVE_NUM_SENSITIVE.size() == 0) { 
      NEGATIVE_NUM_SENSITIVE.addAll(TOKENs.keySet()); 
      NEGATIVE_NUM_SENSITIVE.remove(')'); 
    } 
    return NEGATIVE_NUM_SENSITIVE; 
  } 
  public static boolean isTerminateToken(final char token) { 
    Set keys = TOKENs.keySet(); 
    return keys.contains(token); 
  } 
  public static int getTokenId(final char token) { 
    return TOKENs.get(token) == null ? -1 : TOKENs.get(token); 
  } 
  public static int getTokenSize() { 
    return TOKENs.size(); 
  } 
} 
enum CALCULATE_MODE { 
  INSTANCE; 
  private static char[][] RULES = { 
      // + - * / ( ) # 
      { '>', '>', '<', '<', '<', '>', '>' }, // + 
      { '>', '>', '<', '<', '<', '>', '>' }, // - 
      { '>', '>', '>', '>', '<', '>', '>' }, // * 
      { '>', '>', '>', '>', '<', '>', '>' }, // / 
      { '<', '<', '<', '<', '<', '=', 'o' }, // ( 
      { '>', '>', '>', '>', 'o', '>', '>' }, // ) 
      { '<', '<', '<', '<', '<', 'o', '=' }, // # 
  }; 
  static { 
    if (RULES.length != TERMINATE_TOKENS.getTokenSize() || RULES.length < 1 
 || RULES[0].length != TERMINATE_TOKENS.getTokenSize()) { 
      throw new IllegalArgumentException("Rules matrix is incorrect!"); 
    } 
  } 
  public static char getRule(final char currentOperator, final char opStackTop) { 
    try { 
      return RULES[TERMINATE_TOKENS.getTokenId(opStackTop)][TERMINATE_TOKENS 
   .getTokenId(currentOperator)]; 
    } catch (Throwable e) { 
      throw new RuntimeException("No rules were defined for some token!"); 
    } 
  } 
} 
enum TOKENIZER { 
  INSTANCE; 
  private static final StringBuilder BUFFER = new StringBuilder(); 
  private static String clearexpression(String expression) { 
    return expression.replaceAll(" ", ""); 
  } 
  private static Character PREVIOUS_CHAR; 
  private static void clean() { 
    BUFFER.delete(0, BUFFER.length()); 
    PREVIOUS_CHAR = null; 
  } 
  private static boolean processNegativeNumbers(final String exp, 
      final int index) { 
    char c = exp.charAt(index); 
    if (('+' == c || '-' == c) 
 && (PREVIOUS_CHAR == null || TERMINATE_TOKENS 
     .getNegativeNumSensitiveToken().contains(PREVIOUS_CHAR)) 
 && !TERMINATE_TOKENS.isTerminateToken(exp.charAt(index + 1))) { 
      BUFFER.append(c); 
      return true; 
    } 
    return false; 
  } 
  @SuppressWarnings({ "unchecked", "rawtypes" }) 
  public static List exec(final String expression) { 
    clean(); 
    String exp = clearexpression(expression); 
    List result = new linkedList(); 
    for (int i = 0; i < exp.length(); i++) { 
      char c = exp.charAt(i); 
      if (TERMINATE_TOKENS.isTerminateToken(c)) { 
 if (processNegativeNumbers(exp, i)) 
   continue; 
 if (BUFFER.length() > 0) { 
   result.add(Double.valueOf(BUFFER.toString())); 
   BUFFER.delete(0, BUFFER.length()); 
 } 
 result.add(c); 
      } else { 
 BUFFER.append(c); 
      } 
      PREVIOUS_CHAR = c; 
    } 
    return Collections.unmodifiableList(result); 
  } 
}

输出

4+(3*(3-1)+2)/2 = 8.0
4 + (-3 * ( 3 - 1 ) + 2) = 0.0
4.5+(3.2+3)/2 = 7.6
-4.5+(3.2-3)/2 = -4.4
Incorret expression: 4 +-/ (-3 * ( 3 - 1 ) + 2)
Error: null
Incorret expression: 4.5+(3.2:3)/2
Error: For input string: "3.2:3"

总结

以上就是本文关于Java实现四则混合运算代码示例的全部内容,希望对大家有所帮助。感兴趣的朋友可以参阅:大话Java混合运算规则  浅谈Java变量赋值运算符及相关实例  Java大数字运算之BigInteger 等,有什么问题可以随时留言,小编会及时回复大家的。感谢朋友们对考高分网网站的支持。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/143910.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号