欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2024-04-01 17:50:52
使用栈来实现,可以处理运算优先级。 使用自然四则运算表达式即可,如:4+(3*(3-1)+2)/2。无需把表达式先转换为逆波兰等形式。 package co...

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

使用自然四则运算表达式即可,如: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<double> numstack = new stack<double>(); 
  private final stack<character> opstack = new stack<character>(); 
  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: %s\nerror: %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<character, integer> tokens = new hashmap<character, integer>(); 
  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<character> negative_num_sensitive = new hashset<character>(); 
  public static synchronized set<character> 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<character> 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 等,有什么问题可以随时留言,小编会及时回复大家的。感谢朋友们对网站的支持。