Прошу помощи. Не могу понять что не устраивает валидатор.
Тесты из комментариев совпадают,
Еще вопрос "-1" - одна операция, "-0" как тоже одна операция?
package com.javarush.task.task34.task3404;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Locale;
import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/*
Рекурсия для мат. выражения
*/
public class Solution {
public static void main(String[] args) {
Solution solution = new Solution();
solution.recurse("sin(2*(-5+1.5*4)+28)", 0);
solution.recurse("tan(2025 ^ 0.5)", 0);
}
public void recurse(final String expression, int countOperation) {
Pattern pattern = Pattern.compile("^-?\\d+(\\.\\d+)*$");
String expr = expression.replaceAll(" ", "");
if (pattern.matcher(expr).find()) {
NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.ENGLISH);
numberFormat.setRoundingMode(RoundingMode.HALF_EVEN);
DecimalFormat decimalFormat = (DecimalFormat) numberFormat;
decimalFormat.applyPattern("#.##");
String done = decimalFormat.format(new Double(expr));
if (done.startsWith("-") && countOperation == 0) {
countOperation++;
}
done = done.replaceAll("^-0(\\.0+)?$", "0");
System.out.println("" + done + " " + countOperation + "");
return;
}
String calc = calcReversePolishNotation(expr);
recurse(calc.split(" ")[0], Integer.parseInt(calc.split(" ")[1]));
}
public String calcReversePolishNotation(String expr) {
Pattern pattern;
pattern = Pattern.compile("(^|\\+|-|\\*|/|⨦|≂|\\(|\\^)\\+");
while (pattern.matcher(expr).find()) {
expr = pattern.matcher(expr).replaceAll("$1⨦");
}
pattern = Pattern.compile("(^|\\+|-|\\*|/|⨦|≂|\\(|\\^)-");
while (pattern.matcher(expr).find()) {
expr = pattern.matcher(expr).replaceAll("$1≂");
}
Pattern pattern1 = Pattern.compile("^\\d+(\\.\\d+)*");
Pattern pattern2 = Pattern.compile("^(⨦|≂|sin|cos|tan|\\^)");
Pattern pattern3 = Pattern.compile("^\\(");
Pattern pattern4 = Pattern.compile("^\\)");
Pattern pattern5 = Pattern.compile("^(\\+|-|\\*|/)");
Stack<String> output = new Stack<>();
Stack<String> stack = new Stack<>();
while (expr.length() > 0) {
Matcher matcher1 = pattern1.matcher(expr);
Matcher matcher2 = pattern2.matcher(expr);
Matcher matcher3 = pattern3.matcher(expr);
Matcher matcher4 = pattern4.matcher(expr);
Matcher matcher5 = pattern5.matcher(expr);
if (matcher1.find()) {
String number = matcher1.group();
output.push(number);
expr = expr.substring(number.length());
} else if (matcher2.find()) {
stack.push(matcher2.group());
expr = expr.substring(matcher2.group().length());
} else if (matcher3.find()) {
stack.push(matcher3.group());
expr = expr.substring(matcher3.group().length());
} else if (matcher4.find()) {
while (!stack.peek().equals("(")) {
output.push(stack.pop());
}
stack.pop();
expr = expr.substring(matcher4.group().length());
} else if (matcher5.find()) {
while (stack.size() > 0 && (
stack.peek().matches("^(⨦|≂|sin|cos|tan|\\^)$")
|| (priority(stack.peek()) >= priority(matcher5.group()))
)) {
output.push(stack.pop());
}
stack.push(matcher5.group());
expr = expr.substring(matcher5.group().length());
}
}
while (stack.size() > 0) {
output.push(stack.pop());
}
Stack<Double> calc = new Stack<>();
int count = 0;
double temp;
while (!output.isEmpty()) {
String token = output.remove(0);
switch (token) {
case "+": {
count++;
temp = calc.pop() + calc.pop();
break;
}
case "-": {
count++;
temp = -calc.pop() + calc.pop();
break;
}
case "*": {
count++;
temp = calc.pop() * calc.pop();
break;
}
case "/": {
count++;
double division = calc.pop();
double divisor = calc.pop();
temp = divisor / division;
break;
}
case "^": {
count++;
double power = calc.pop();
double number = calc.pop();
temp = Math.pow(number, power);
break;
}
case "⨦": {
count++;
temp = calc.pop();
break;
}
case "≂": {
count++;
temp = -calc.pop();
break;
}
case "sin": {
count++;
temp = Math.sin(Math.toRadians(calc.pop()));
break;
}
case "cos": {
count++;
temp = Math.cos(Math.toRadians(calc.pop()));
break;
}
case "tan": {
count++;
temp = Math.tan(Math.toRadians(calc.pop()));
break;
}
default: {
temp = Double.parseDouble(token);
break;
}
}
NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.ENGLISH);
numberFormat.setRoundingMode(RoundingMode.HALF_EVEN);
DecimalFormat decimalFormat = (DecimalFormat) numberFormat;
decimalFormat.applyPattern("#.##");
calc.push(new Double(decimalFormat.format(temp)));
}
NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.ENGLISH);
numberFormat.setRoundingMode(RoundingMode.HALF_EVEN);
DecimalFormat decimalFormat = (DecimalFormat) numberFormat;
decimalFormat.applyPattern("#.##");
String done = decimalFormat.format(calc.pop());
return "" + done + " " + count + "";
}
public int priority(String operation) {
switch (operation) {
case "+":
case "-": {
return 1;
}
case "*":
case "/": {
return 2;
}
case "^": {
return 3;
}
default: {
return 0;
}
}
}
public Solution() {
//don't delete
}
}