I adjusted my code. Now it does see it as recursion, but it is still saying the answer is wrong? Why? Even my calculator says every answer is as expected? Who can find the error? I'm currently at attempt 30 to get this thing finished.
package com.codegym.task.task34.task3404;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/*
Recursion for mathematical expressions
*/
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
solution.recurse("tan(2025 ^ 0.5)", 0); // Expected output: 1 2
solution.recurse("1+2.41+1", 0); // Expected 4.41 1
solution.recurse("2^2", 0); // Expected 4 1
solution.recurse(" 3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3", 0); //Expected 3 6
}
public void recurse(final String expression, int countOperation) {
//implement
String currentExpression = expression;
if (countOperation == 0) {
countOperation = getOperationsCount(expression);
}
if (isNumber(currentExpression)) {
NumberFormat numberFormat = new DecimalFormat("#.##");
Double result = Double.parseDouble(currentExpression);
System.out.println(String.format("%s %d", numberFormat.format(result), countOperation));
return;
} else if (currentExpression.contains("(")) {
int lastParenthStart = currentExpression.lastIndexOf("(");
int lastParenthEnd = currentExpression.indexOf(")", lastParenthStart);
String mostInnerExpr = currentExpression.substring(lastParenthStart + 1, lastParenthEnd);
String innerFunction = lastParenthStart > 2 ? expression.substring(lastParenthStart - 3, lastParenthStart) : "nop";
if (isNumber(mostInnerExpr)) {
double mostInnerResult = Double.parseDouble(mostInnerExpr);
switch (innerFunction) {
case "sin":
mostInnerResult = Math.sin(mostInnerResult * Math.PI / 180);
lastParenthStart -= 3;
break;
case "cos":
mostInnerResult = Math.cos(mostInnerResult * Math.PI / 180);
lastParenthStart -= 3;
break;
case "tan":
mostInnerResult = Math.tan(mostInnerResult * Math.PI / 180);
lastParenthStart -= 3;
break;
}
currentExpression = currentExpression.substring(0, lastParenthStart)
.concat(String.valueOf(mostInnerResult))
.concat(currentExpression.substring(lastParenthEnd + 1));
} else {
// Expression in innermost block
if (innerFunction.equalsIgnoreCase("sin") || innerFunction.equalsIgnoreCase("cos") || innerFunction.equalsIgnoreCase("tan")) {
currentExpression = currentExpression.substring(0, lastParenthStart + 1)
.concat(String.valueOf(calcExpression(mostInnerExpr)))
.concat(currentExpression.substring(lastParenthEnd));
} else {
currentExpression = currentExpression.substring(0, lastParenthStart)
.concat(String.valueOf(calcExpression(mostInnerExpr)))
.concat(currentExpression.substring(lastParenthEnd + 1));
}
}
} else {
currentExpression = String.valueOf(calcExpression(currentExpression));
}
recurse(currentExpression, countOperation);
}
private double calcExpression(String expression) {
String sum = expression;
while (sum.contains("^") || sum.contains("*") || sum.contains("/") || sum.contains("+") || sum.contains("-") && !sum.startsWith("-")) {
if (sum.contains("^")) {
int index = sum.indexOf("^");
double[] aIndex = findA(sum, index);
double[] bIndex = findB(sum, index);
double answer = Math.pow(aIndex[0], bIndex[0]);
sum = sum.substring(0, (int) aIndex[1]) + answer + sum.substring((int) bIndex[1]);
} else if (sum.contains("*")) {
int index = sum.indexOf("*");
double[] aIndex = findA(sum, index);
double[] bIndex = findB(sum, index);
double answer = aIndex[0] * bIndex[0];
sum = sum.substring(0, (int) aIndex[1]) + answer + sum.substring((int) bIndex[1]);
} else if (sum.contains("/")) {
int index = sum.indexOf("/");
double[] aIndex = findA(sum, index);
double[] bIndex = findB(sum, index);
double answer = aIndex[0] / bIndex[0];
sum = sum.substring(0, (int) aIndex[1]) + answer + sum.substring((int) bIndex[1]);
} else if (sum.contains("+")) {
int index = sum.indexOf("+");
double[] aIndex = findA(sum, index);
double[] bIndex = findB(sum, index);
double answer = aIndex[0] + bIndex[0];
sum = sum.substring(0, (int) aIndex[1]) + answer + sum.substring((int) bIndex[1]);
} else if (sum.contains("-")) {
int index = sum.indexOf("-");
double[] aIndex = findA(sum, index);
double[] bIndex = findB(sum, index);
double answer = aIndex[0] - bIndex[0];
sum = sum.substring(0, (int) aIndex[1]) + answer + sum.substring((int) bIndex[1]);
}
}
return Double.parseDouble(sum);
}
private double[] findA(String sum, int index){
StringBuilder stringBuilder = new StringBuilder();
double[] a = new double[2];
for (int i = index-1; i >= 0; i--){
if (sum.charAt(i) == '^' || sum.charAt(i) == '*' || sum.charAt(i) == '/' || sum.charAt(i) == '+'){
a[1] = i+1;
break;
}
if (sum.charAt(i) == '-' && i != 0 && sum.charAt(i-1) != '^' && sum.charAt(i-1) != '*' && sum.charAt(i-1) != '/' && sum.charAt(i-1) != '+' && sum.charAt(i-1) != '-'){
}
stringBuilder.insert(0, sum.charAt(i));
if (i == 0){
a[1] = i;
}
}
try{
a[0] = Double.parseDouble(stringBuilder.toString());
}catch (Exception e){
int x = Integer.parseInt(stringBuilder.toString());
a[0] = x * 1.0;
}
return a;
}
private double[] findB(String sum, int index){
StringBuilder stringBuilder = new StringBuilder();
double[] b = new double[2];
for (int i = index+1; i < sum.length(); i++){
if (sum.charAt(i) == '^' || sum.charAt(i) == '*' || sum.charAt(i) == '/' || sum.charAt(i) == '+' || sum.charAt(i) == '-' && i != index+1){
b[1] = i;
break;
}
stringBuilder.append(sum.charAt(i));
if (i == sum.length()-1){
b[1] = i+1;
}
}
try{
b[0] = Double.parseDouble(stringBuilder.toString());
}catch (Exception e){
int x = Integer.parseInt(stringBuilder.toString());
b[0] = x * 1.0;
}
return b;
}
private boolean isNumber(String expression) {
if (expression == null) return false;
return expression.matches("^[+-]?\\d+(\\.\\d+)?");
}
public Solution() {
//don't delete
}
private int getOperationsCount(String expression) {
String[] operations = new String[] {"sin", "cos", "tan", "\\^", "\\+", "\\-", "\\*", "\\/"};
int operationsCount = 0;
for (String operation : operations) {
operationsCount += expression.split(operation).length - 1;
}
return operationsCount;
}
}