Оцените такую версию калькулятора
Написал простой калькулятор, выполняет действия +-/. Ввод через одну строку. Пример: 10+(36+1). Хотел бы услышать критику, ну и может что где подправить. Заранее спасибо!
import java.text.CharacterIterator;
import java.text.StringCharacterIterator;
import java.util.ArrayList;
import java.util.Objects;
import java.util.Scanner;
import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("\t\tКалькулятор\u260a\n\tЩоб вийти введіть 'n'");
while (true) {
System.out.println("\nEnter: ");
String input = extractValuesInBrackets(in.nextLine());
if(Objects.equals(input, "n")) break;
System.out.println(calculate(parseNumbers(input), readMathOperators(input)));
}
}
public static String extractValuesInBrackets(String input) {
String expression = input;
Stack<Integer> stack = new Stack<>();
for (int i = 0; i < expression.length(); i++) {
if (expression.charAt(i) == '(') {
stack.push(i);
} else if (expression.charAt(i) == ')') {
if (!stack.isEmpty()) {
int start = stack.pop();
String valueInBrackets = expression.substring(start, i + 1);
Double result = calculate(parseNumbers(valueInBrackets),
readMathOperators(valueInBrackets));
expression = expression.replace(valueInBrackets, result.toString());
i = 0;
}
}
}
return expression;
}
public static ArrayList<Character> readMathOperators(String input){
ArrayList <Character> op = new ArrayList<>();
String removeMinusInput;
if(input.startsWith("-"))
removeMinusInput = input.substring(1);
else if (input.startsWith("(-"))
removeMinusInput = input.substring(2);
else
removeMinusInput = input;
CharacterIterator it = new StringCharacterIterator(removeMinusInput);
while (it.current() != CharacterIterator.DONE)
{
if((it.current() == '+' || it.current() == '-' ||
it.current() == '*' || it.current() == '/')) {
op.add(it.current());
if(it.next() == '-') it.next();
}
it.next();
}
return op;
}
public static ArrayList<Double> parseNumbers(String input){
Pattern pattern = Pattern.compile("-?\\d+(\\.\\d+)?");
Matcher matcher = pattern.matcher(input);
ArrayList <Double> Al = new ArrayList<>();
try {
while (matcher.find()) {
String match = matcher.group();
if (input.startsWith("-") && matcher.start() == 0){
Al.add(Double.parseDouble(match));
continue;
}
if (match.startsWith("-") && input.charAt(matcher.start() - 1) != '(') {
if(input.charAt(matcher.start()-1) != '*' &&
input.charAt(matcher.start()-1) != '-' &&
input.charAt(matcher.start()-1) != '+' &&
input.charAt(matcher.start()-1) != '/')
match = match.substring(1);
}
Al.add(Double.parseDouble(match));
}
}catch (NumberFormatException e) {
System.out.println("Невозможно преобразовать строку в число\n");
}
return Al;
}
public static Double calculate(ArrayList<Double> Al, ArrayList<Character> op){
while (op.contains('*') || op.contains('/')) {
for (int i = 0; i < op.size(); i++) {
if (op.get(i) == '*') {
Al.set(i, Al.get(i) * Al.get(i + 1));
Al.remove(i + 1);
op.remove(i);
break;
}
if (op.get(i) == '/') {
Al.set(i, Al.get(i) / Al.get(i + 1));
Al.remove(i + 1);
op.remove(i);
break;
}
}
}
while (!op.isEmpty()) {
if (op.getFirst() == '+') {
Al.set(0, Al.get(0) + Al.get(1));
Al.remove(1);
op.remove(0);
} else if (op.getFirst() == '-') {
Al.set(0, Al.get(0) - Al.get(1));
Al.remove(1);
op.remove(0);
}
else break;
}
return Al.getFirst();
}
}