Голова не варит уже от этой задачи. Валидатор не пропускает.
Подскажите, на каких примерах еще потестить плз.
package com.javarush.task.task34.task3404;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
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); //expected output 0.5 6
System.out.println();
solution.recurse("1+(1+(1+1)*(1+1))*(1+1)+1", 0); // 12 8
System.out.println();
solution.recurse("-2^(-2)",0); // -0.25 3
System.out.println();
solution.recurse("-(-2^(-2))+2+(-(-2^(-2)))",0); // 2.5 10
System.out.println();
solution.recurse("(-2)*(-2)",0);
System.out.println();
solution.recurse("(-2)/(-2)",0);
System.out.println();
solution.recurse("sin(-30)",0);
System.out.println();
solution.recurse("cos(-30)",0);
System.out.println();
solution.recurse("tan(-30)",0);
System.out.println();
solution.recurse("2+8*(9/4-1.5)^(1+1)",0);
System.out.println();
solution.recurse("tan(44+sin(89-cos(180)^2))",0);
System.out.println();
solution.recurse("-cos(180)^2",0);
System.out.println();
solution.recurse("0+0.304",0);
}
public void recurse(final String expression1, int countOperation) {
String expression = deleteSpaces(expression1);
if (isSingleExpression(expression)){
DecimalFormat df2 = new DecimalFormat("#.##");
int newCount = countOperation + countOperation(expression);
// df2.setRoundingMode(RoundingMode.UP);
System.out.print(df2.format(calculateSingleExpression(expression))+ " " + newCount);
return;
}
if (expression.contains("(")) {
StringBuilder s = new StringBuilder(expression);
int i = 0, j = 0;
while (s.charAt(j) != ')') {
if (s.charAt(j) == '(') i = j;
j = j + 1;
}
String subString = s.substring(i+1, j );
int countedOperation = countOperation(subString);
double calcExpression = calculate(subString);
////// ------- вводим m для обозначения вычисленного отрицат выражения, чтобы в дальнейшем не считать этот минус как операцию
String replacesStr ;
if (calcExpression <0) replacesStr = "m" + String.valueOf(-1*calcExpression);
else replacesStr = String.valueOf(calcExpression);
String resultString = s.replace(i, j + 1, replacesStr).toString();
recurse(resultString, countOperation+countedOperation);
}
else {
double calcExpression = calculate(expression);
////// ------- вводим m для обозначения вычисленного отрицат выражения, чтобы в дальнейшем не считать этот минус как операцию
String replacesStr ;
if (calcExpression <0) replacesStr = "m" + String.valueOf(-1*calcExpression);
else replacesStr = String.valueOf(calcExpression);
recurse(replacesStr,countOperation+countOperation(expression));
}
}
public Solution() {
//don't delete
}
/* private boolean isDigit(String expression){
Pattern pattern = Pattern.compile("[0-9]*[.]?[0-9]+");
Matcher matcher = pattern.matcher(expression);
while (matcher.find()){
if (expression.equals(expression.substring(matcher.start(),matcher.end()))) return true;
break;
}
return false;
}
*/
private String deleteSpaces(String expression){
// StringBuilder sb = new StringBuilder(expression);
if (!expression.contains(" ")) return expression;
return expression.replace(" ","");
}
/* private String hideMinuses(String expression){
if (!expression.contains("-")) return expression;
StringBuilder sb = new StringBuilder(expression);
Pattern pattern = Pattern.compile("[0-9]*[.]?[0-9]+\\-[0-9]*[.]?[0-9]+");
Matcher matcher = pattern.matcher(sb);
while (matcher.find()){
String result = sb.substring(matcher.start(),matcher.end());
sb.replace(matcher.start(),matcher.end(),result.replace("-","+M"));
}
pattern = Pattern.compile("\\-");
matcher = pattern.matcher(sb);
while (matcher.find()){
// String result = sb.substring(matcher.start(),matcher.end());
sb.replace(matcher.start(),matcher.end(),"M");
}
return sb.toString();
}
*/
public int countOperation(String expression) {
int count = 0;
Pattern pattern = Pattern.compile("\\+|\\-|\\*|\\/|\\^|sin|cos|tan");
Matcher matcher = pattern.matcher(expression);
while (matcher.find()){
count++;
}
return count;
}
public boolean isSingleExpression(String expression){
if (expression.contains("(")) return false;
List<String> operations = new ArrayList<>();
Pattern pattern = Pattern.compile("\\+|\\-|\\*|\\^|\\/|sin|cos|tan");
Matcher matcher = pattern.matcher(expression);
while (matcher.find()){
String result = expression.substring(matcher.start(),matcher.end());
operations.add(result);
}
if (operations.size()>1) return false;
return true;
}
private double calculate(String expression){
double result = 0;
if (isSingleExpression(expression)){
return calculateSingleExpression(expression);
}
String[] summand;
if (expression.contains("+")) {
summand = expression.split("\\+");
if (summand.length != 0) {
for (int i = 0; i < summand.length; i++) {
result += calculate(summand[i]);
}
return result;
}
}
if (expression.contains("-")){
summand = expression.split("\\-");
if (summand.length!=0) {
result = calculate(summand[0]);
for (int i = 1; i < summand.length;i++) {
result -= calculate(summand[i]);
}
return result;
}
}
if (expression.contains("*")) {
summand = expression.split("\\*");
if (summand.length != 0) {
result = calculate(summand[0]);
for (int i = 1; i < summand.length; i++) {
result *= calculate(summand[i]);
}
return result;
}
}
if (expression.contains("/")) {
summand = expression.split("\\/");
if (summand.length != 0) {
result = calculate(summand[0]);
for (int i = 1; i < summand.length; i++) {
result /= calculate(summand[i]);
}
return result;
}
}
if (expression.contains("^")){
summand = expression.split("\\^");
if (summand.length != 0) {
result = calculate(summand[0]);
for (int i = 1; i < summand.length; i++) {
result = Math.pow(result,calculate(summand[i]));
}
return result;
}
}
return result;
}
public double calculateSingleExpression(String expression){
if (expression.equals("")) return 0;
if (!isSingleExpression(expression)){
throw new IllegalArgumentException("Expression is not single");
}
List<String> args = new ArrayList<String>();
List<String> signs = new ArrayList<String>();
// Pattern pattern = Pattern.compile("([Mm]|Mm)?[0-9]*[.]?[0-9]+");
Pattern pattern = Pattern.compile("[m]?[0-9]*[.]?[0-9]+");
Matcher matcher;
matcher = pattern.matcher(expression);
while (matcher.find()){
String result = expression.substring(matcher.start(),matcher.end());
args.add(result);
}
// pattern = Pattern.compile("\\+|\\-|\\*|\\/|\\^|sin|cos|tan|Msin|Mcos|Mtan");
pattern = Pattern.compile("\\+|\\-|\\*|\\/|\\^|sin|cos|tan|sin|cos|tan");
matcher = pattern.matcher(expression);
while (matcher.find()){
String result = expression.substring(matcher.start(),matcher.end());
signs.add(result);
}
//arguments
Double a=0.0,b;
if (args.get(0).contains("m")) args.set(0, args.get(0).replace('m', '-'));
a = Double.parseDouble(args.get(0));
// Initialize b if exists
try {
if (args.get(1).contains("m")) args.set(1, args.get(1).replace('m', '-'));
b = Double.parseDouble(args.get(1));
}catch (IndexOutOfBoundsException e){
b=0.0;
}
if (signs.size() == 0) {
return a;
}
switch (signs.get(0)) {
case "*":
return a*b;
case "/":
return a/b;
case "+":
return a+b;
case "-":
if (args.size()==1) return -a;
return a-b;
case "^":
return Math.pow(a,b);
case "sin":
return Math.sin(a*Math.PI/180);
case "cos":
return Math.cos(a*Math.PI/180);
case "tan":
return Math.tan(a*Math.PI/180);
/* case "Msin":
return -Math.sin(a*Math.PI/180);
case "Mcos":
return -Math.cos(a*Math.PI/180);
case "Mtan":
return -Math.tan(a*Math.PI/180);
*/
default: return 0;
}
}
}