当前位置: 移动技术网 > IT编程>开发语言>Java > Java实现四则混合运算代码示例

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

2019年07月19日  | 移动技术网IT编程  | 我要评论

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

使用自然四则运算表达式即可,如: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 等,有什么问题可以随时留言,小编会及时回复大家的。感谢朋友们对移动技术网网站的支持。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网