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 等,有什么问题可以随时留言,小编会及时回复大家的。感谢朋友们对网站的支持。