使用栈来实现,可以处理运算优先级。
使用自然四则运算表达式即可,如: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: %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 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', '>', '>' }, // )
{ '
};
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等,有什么问题可以随时留言,小编会及时回复大家的。感谢朋友们对萬仟网网站的支持。
希望与广大网友互动??
点此进行留言吧!