- 程序的可继续开发性,由于使用了大量的集合函数等,使得程序在继续开发和维护上具有较大优势
- 输入后可以判定是否输入了中文的符号,并给出相应的提示
- 输入后可以判定是否有连续的运算符出现,如++,*+等,如果出现操作符杂糅,可以直接提示.
- 可以在括号前省略*,这样更符合正常书写模式习惯,如输入2(1+1)也是可以支持转换为2*(1+1)的,这点还是犹豫再一次测试输入的时候犹豫手写的输入惯性漏加上*后想到可以增添的功能
- 输入后可以检测到是负号-还是减号-,并且正确处理负号.
- 支持对于科学计数法的输入如1e2,2e-2的支持,将e看作是数字的一部分之后将整个string传给ScienceCal方法,由其方法将数字转换为正常的表达方式.
- 支持大数的四则运算,运算方式是采用了JAVA的库BigInteger
import java.math.BigInteger;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;
import java.util.Stack;
class Cal {
private enum Operator {
ADD("+", 10), SUBTRACT("-", 10),
MULTIPLY("*", 20), DIVIDE("/", 20),
EXPONENT("^", 30), REMAINDER("%", 40),
PARENTHESIS_LEFT("(", 100), PARENTHESIS_RIGHT(")", 100);
private String operator;
private int priority;
private Operator(String operator, int priority) {
this.operator = operator;
this.priority = priority;
}
}
private enum Operand {
ONE("1"), TWO("2"), THREE("3"), FOUR("4"), FIVE("5"), SIX("6"),
SEVEN("7"), EIGHT("8"), NINE("9"), ZERO("0"), POINT("."), Science("e");
private String operand;
private Operand(String operand) {
this.operand = operand;
}
}
private Operator getOperator(String str) {
for (Operator op : Operator.values()) {
if (str.equals(op.operator)) {
return op;
}
}
return null;
}
private Operand getOperand(String str) {
for (Operand op : Operand.values()) {
if (str.equals(op.operand)) {
return op;
}
}
return null;
}
private String ScienceCal(String x) {
int EPoint = x.indexOf('e');
if (EPoint == -1) {
return x;
}
else {
String head = x.substring(0, EPoint);
String back = x.substring(EPoint + 1);
double a = 0.0;
double b = 0.0;
try {
a = Double.parseDouble(head);
b = Double.parseDouble(back);
} catch (NumberFormatException e) {
System.out.println("操作数非法! ");
e.printStackTrace();
}
return String.valueOf(a * Math.pow(10, b));
}
}
private List<String> resolveExpr(String exp) {
List<String> list = new LinkedList<String>();
String temp = "";
exp = exp.replace(" ", "");
for (int i = 0; i < exp.length(); i++) {
if (exp.charAt(i) == '(') {
System.out.println("使用了中文字符'('");
return null;
}
if (exp.charAt(i) == ')') {
System.out.println("使用了中文字符')'");
return null;
}
if (exp.charAt(i) == '。') {
System.out.println("使用了中文字符。");
}
}
StringBuilder exptmp = new StringBuilder();
exptmp.append(exp.charAt(0));
for (int i = 1; i < exp.length(); i++) {
char c = exp.charAt(i);
String str = exp.substring(i - 1, i);
Operand od = getOperand(str);
if (c == '(' && (od != null || exp.charAt(i - 1) == ')')) {
exptmp.append("*(");
continue;
}
exptmp.append(c);
}
exp = "" + exptmp;
if (exp.charAt(0) == '-') {
exp = "0" + exp;
}
if (exp.charAt(0) == '+' || exp.charAt(0) == '*' || exp.charAt(0) == '/'
|| exp.charAt(0) == '^' || exp.charAt(0) == '%') {
System.out.println("运算符杂糅! ");
return null;
}
if (exp.charAt(0) == ')') {
System.out.println("缺少左括号! ");
return null;
}
for (int i = 0; i < exp.length(); i++) {
String str = exp.substring(i, i + 1);
Operator op = getOperator(str);
Operand od = getOperand(str);
if (op != null) {
if (!temp.isEmpty() && exp.charAt(i - 1) == 'e' && exp.charAt(i) == '-' && i > 0) {
temp += '-';
}
else if (!temp.isEmpty()) {
list.add(ScienceCal(temp));
temp = "";
list.add(str);
}
else if (i > 0) {
if (exp.charAt(i) == '-' && (exp.charAt(i - 1) == '-' || exp.charAt(i - 1) == '+'
|| exp.charAt(i - 1) == '*' || exp.charAt(i - 1) == '^'
|| exp.charAt(i - 1) == '(')) {
temp += str;
}
else if ((exp.charAt(i) == '+' || exp.charAt(i) == '^' || exp.charAt(i) == '*'
|| exp.charAt(i) == '/' || exp.charAt(i) == '%') && (exp.charAt(i - 1) == '+'
|| exp.charAt(i - 1) == '-' || exp.charAt(i - 1) == '*' || exp.charAt(i - 1) == '/'
|| exp.charAt(i - 1) == '^' || exp.charAt(i - 1) == '%')) {
System.out.println("运算符杂糅! ");
return null;
}
else {
list.add(str);
}
}
else {
list.add(str);
}
}
else if (od != null) {
temp += str;
}
else {
System.out.println("存在非法符号" + str);
return null;
}
}
if (!temp.isEmpty()) {
list.add(ScienceCal(temp));
}
return list;
}
private List<String> dealExpr(List<String> expList) {
if (expList == null) {
return null;
}
List<String> list = new LinkedList<String>();
Stack<String> stack = new Stack<String>();
for (String str : expList) {
Operator op = getOperator(str.substring(0, 1));
Operand od = getOperand(str.substring(0, 1));
if (od != null || str.length() > 1) {
list.add(str);
}
else if (op != null) {
if (Operator.PARENTHESIS_LEFT.equals(op)) {
stack.push(str);
}
else if (Operator.PARENTHESIS_RIGHT.equals(op)) {
while (true) {
if (stack.empty()) {
System.out.println("缺少左括号! ");
return null;
}
else if (Operator.PARENTHESIS_LEFT.operator.equals(stack.peek())) {
stack.pop();
break;
}
else {
list.add(stack.pop());
}
}
}
else {
if (!stack.empty()) {
Operator top_op = getOperator(stack.peek());
if (op.priority > top_op.priority
|| Operator.PARENTHESIS_LEFT.equals(top_op)) {
stack.push(str);
}
else {
list.add(stack.pop());
stack.push(str);
}
}
else {
stack.push(str);
}
}
}
}
while (!stack.empty()) {
String str = stack.peek();
if (Operator.PARENTHESIS_LEFT.operator.equals(str)) {
System.out.println("缺少右括号! ");
return null;
}
else {
list.add(stack.pop());
}
}
return list;
}
private String operation(String x, String y, Operator op) {
int xisPoint = x.indexOf('.');
int yisPoint = y.indexOf('.');
if (xisPoint == -1 && yisPoint == -1) {
if (x.length() < 9 && y.length() < 9) {
int a = 0;
int b = 0;
try {
a = Integer.parseInt(x);
b = Integer.parseInt(y);
} catch (NumberFormatException e) {
System.out.println("操作数非法! ");
e.printStackTrace();
}
switch (op) {
case ADD:
return String.valueOf(a + b);
case SUBTRACT:
return String.valueOf(a - b);
case MULTIPLY:
return String.valueOf(a * b);
case DIVIDE:
double aa = Double.parseDouble(x);
double bb = Double.parseDouble(y);
if (b == 0) {
System.out.println("进行了除0操作! ");
return null;
}
else {
return String.valueOf(aa / bb);
}
case EXPONENT:
return String.valueOf(Math.pow(a, b));
case REMAINDER:
return String.valueOf(a % b);
default:
return null;
}
}
else {
BigInteger a = new BigInteger(x);
BigInteger b = new BigInteger(y);
switch (op) {
case ADD:
return a.add(b).toString();
case SUBTRACT:
return a.subtract(b).toString();
case MULTIPLY:
return a.multiply(b).toString();
case DIVIDE:
if (b.intValue() == 0) {
System.out.println("进行了除0操作! ");
return null;
}
else {
return a.divide(b).toString();
}
case EXPONENT:
System.out.println("大整数不支持乘方运算");
return null;
case REMAINDER:
System.out.println("大整数不支持求余操作");
return null;
default:
return null;
}
}
}
else {
double a = 0.0;
double b = 0.0;
try {
a = Double.parseDouble(x);
b = Double.parseDouble(y);
} catch (NumberFormatException e) {
System.out.println("操作数非法! ");
e.printStackTrace();
}
switch (op) {
case ADD:
return String.valueOf(a + b);
case SUBTRACT:
return String.valueOf(a - b);
case MULTIPLY:
return String.valueOf(a * b);
case DIVIDE:
return String.valueOf(a / b);
case EXPONENT:
return String.valueOf(Math.pow(a, b));
case REMAINDER:
System.out.println("非整数不能进行求余操作");
return null;
default:
return null;
}
}
}
public String calculate(String exp) {
List<String> expList = dealExpr(resolveExpr(exp));
if (expList == null) {
return null;
}
Stack<String> stack = new Stack<String>();
for (String str : expList) {
Operator op = getOperator(str.substring(0, 1));
Operand od = getOperand(str.substring(0, 1));
if (od != null || str.length() > 1) {
stack.push(str);
}
else if (op != null) {
String x = "";
String y = "";
if (!stack.empty()) {
y = stack.pop();
}
if (!stack.empty()) {
x = stack.pop();
}
if (!x.isEmpty() && !y.isEmpty()) {
String result = operation(x, y, op);
if (result == null) {
return null;
}
stack.push(result);
}
else {
return null;
}
}
}
return stack.pop();
}
}
public class Test {
public static void main(String[] args) {
Cal cal = new Cal();
Scanner in = new Scanner(System.in);
String intext = cal.calculate(in.nextLine());
if (intext != null) {
System.out.println(intext);
}
}
}