calculator java_Calculator.java

package zong;

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 {

public static String str1;

public static double answ;

public double getAnsw() {

return answ;

}

public void setAnsw(double answ) {

this.answ = answ;

}

public String getStr1() {

return str1;

}

public void setStr1(String str1) {

this.str1 = str1;

}

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) {

// float answ = (float) (Math.round(numStack.peek() * 10)) / 10;//

setAnsw((Math.round(numStack.peek() * 10)) / 10);// 对结果保留一位小数,如果保留两位,就把10改成100

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();

try {

int op;// 随机选择计算符

int kuo;// 是否在此处加入括号

int[] number = new int[100];

for (int i = 1; i <= 7; i++) {

// XXD:需要多少个数字就修改这里!!!

number[i] = (int) (Math.random() * 9 + 1);

}

int flag = 0;// 是否已经有左括号

int flag2 = 0;// 左右括号之间数字的个数

int cnt = 1;// 已经使用的数字的个数

String str = "";// 储存准备用于计算的运算串

String fuhao;// 储存随机产生的符号

while (true) {

kuo = (int) (Math.random() * 2 + 1);// 是否在此处加入括号

if (kuo == 1 && flag == 0 && cnt != 7) {

str += "(";

flag = 1;

flag2 = 0;

}

str += Integer.toString(number[cnt]);

cnt++;

op = (int) (Math.random() * 4 + 1);// 随机选择计算符

if (op == 1) {

fuhao = "+";

} else if (op == 2) {

fuhao = "-";

} else if (op == 3) {

fuhao = "*";

} else {

fuhao = "/";

}

if (cnt == 8) {// 数字个数上限+1

if (flag == 1)

str += ")";

break;

}

kuo = (int) (Math.random() * 2 + 1);

flag2++;

if (kuo == 1 && flag == 1 && flag2 == 2) {// 随机决定此处加右括号 &&

// 已经有左括号

// && 左右括号之间最少有两个数

str += ")";

flag = 0;

flag2 = 0;

}

str += fuhao;

}

// cal.exec("4+(3*(3-1)+2)/2"); //测试 = 8.0

// cal.exec("4+(-3*(3-1)+2)"); //测试 = 0.0

cal.exec(str);

cal.setStr1(str);

} catch (Exception e) {

e.printStackTrace();

}

}

}

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);

}

}

一键复制

编辑

Web IDE

原始数据

按行查看

历史

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值