22
33import java .math .BigDecimal ;
44import java .util .ArrayDeque ;
5+ import cu .lt .joe .jcalc .ConfigurationBuilder ;
56import cu .lt .joe .jcalc .JCalc ;
67import cu .lt .joe .jcalc .exceptions .SyntaxErrorException ;
78import cu .lt .joe .jcalc .exceptions .UnbalancedParenthesesException ;
@@ -43,30 +44,30 @@ private static int getOperatorPrecedence(String operator)
4344 }
4445
4546 /**
46- * Takes a {@link String} containing a Math expression and applies the Shunting Yard algorithm
47- * to it, returning a {@link String} that contains the result of solving that given expression
48- * or {@code null} when the expression is empty.
47+ * Takes a {@link String} containing a Math expression and a {@link ConfigurationBuilder}
48+ * instance to later use the Shunting Yard algorithm to solve the given expression using the
49+ * settings in the provided {@link ConfigurationBuilder} to determine what precision to apply to
50+ * the final result, whether to attempt to balance parentheses or not, and when to use radians or
51+ * degrees to work with trigonometric functions. At the end, returns a {@link String} that
52+ * contains the result of solving that given expression or {@code null} when the expression is
53+ * empty.
4954 *
50- * @param mathExpression a {@link String} with the Math expression to process with the
51- * Shunting Yard algorithm
52- * @param balanceParentheses a {@code boolean} parameter to specify whether to automatically attempt
53- * to balance the parentheses in the given Math expression
54- * @param precision an {@code int} value to set how precise the result must be
55- * @param useRadians a {@code boolean} to set if trigonometric functions will use radians
56- * or degrees when calculating a result
55+ * @param mathExpression a {@link String} with the Math expression to process with the
56+ * Shunting Yard algorithm
57+ * @param configurationBuilder a {@link ConfigurationBuilder} instance with the settings to
58+ * customize how Math expressions are treated
5759 * @return A {@link String} that contains the result of solving the given Math expression or
5860 * {@code null} when the expression is empty
5961 * @throws UnbalancedParenthesesException when parentheses are not placed correctly and
6062 * {@code balanceParentheses} parameter is set to false
6163 * @author <a href="https://github.com/jr20xx">jr20xx</a>
6264 * @since 3.0.0
6365 */
64- public static String solveMathExpression (String mathExpression , boolean balanceParentheses , int precision , boolean useRadians )
66+ public static String solveMathExpression (String mathExpression , ConfigurationBuilder configurationBuilder )
6567 {
6668 ArrayDeque <BigDecimal > output = new ArrayDeque <>();
6769 ArrayDeque <String > operators = new ArrayDeque <>();
6870 StringBuilder numberBuilder = new StringBuilder ();
69- balanceParentheses = balanceParentheses && (mathExpression .contains ("(" ) || mathExpression .contains (")" ));
7071 int openParenthesesCount = 0 , actualExpressionLength = mathExpression .length () - 1 ;
7172
7273 char previouslyFoundChar = '\u0000' ;
@@ -92,8 +93,8 @@ else if (isFactorialOperator(currentChar + ""))
9293 if (output .isEmpty ())
9394 throw new SyntaxErrorException ("Factorial operator '!' has no preceding number" );
9495 while (!operators .isEmpty () && (isUnaryOperator (operators .peek ()) && !operators .peek ().equals ("u-" )))
95- performStacking (output , operators .pop (), useRadians );
96- performStacking (output , currentChar + "" , useRadians );
96+ performStacking (output , operators .pop (), configurationBuilder . isUseRadiansEnabled () );
97+ performStacking (output , currentChar + "" , configurationBuilder . isUseRadiansEnabled () );
9798 }
9899 else if ((currentChar == '-' || currentChar == '+' ) && (i == 0 || previouslyFoundChar == '(' || (isOperator (previouslyFoundChar + "" ) && !isFactorialOperator (previouslyFoundChar + "" ))))
99100 {
@@ -104,7 +105,7 @@ else if (currentChar == '(')
104105 if (previouslyFoundChar == ')' || isFactorialOperator (previouslyFoundChar + "" ) || isMathConstant (previouslyFoundChar ) || (Character .isDigit (previouslyFoundChar ) && !operators .isEmpty () && !operators .peek ().equals ("log2" )))
105106 operators .push ("*" );
106107 operators .push (currentChar + "" );
107- if (balanceParentheses ) openParenthesesCount ++;
108+ if (configurationBuilder . isBalanceParenthesesEnabled () ) openParenthesesCount ++;
108109 }
109110 else if (currentChar == ')' )
110111 {
@@ -113,16 +114,17 @@ else if (currentChar == ')')
113114 else if (previouslyFoundChar == '(' )
114115 output .push (BigDecimal .ONE );
115116 while (!operators .isEmpty () && !operators .peek ().equals ("(" ))
116- performStacking (output , operators .pop (), useRadians );
117- if (operators .isEmpty () && !balanceParentheses )
117+ performStacking (output , operators .pop (), configurationBuilder . isUseRadiansEnabled () );
118+ if (operators .isEmpty () && !configurationBuilder . isBalanceParenthesesEnabled () )
118119 throw new UnbalancedParenthesesException ("Parentheses are not well placed" );
119120 if (!operators .isEmpty ())
120121 {
121122 operators .pop ();
122- if (balanceParentheses ) openParenthesesCount --;
123+ if (configurationBuilder .isBalanceParenthesesEnabled ())
124+ openParenthesesCount --;
123125 }
124126 if (!operators .isEmpty () && isUnaryOperator (operators .peek ()))
125- performStacking (output , operators .pop (), useRadians );
127+ performStacking (output , operators .pop (), configurationBuilder . isUseRadiansEnabled () );
126128 }
127129 else if (isOperator (currentChar + "" ))
128130 {
@@ -132,7 +134,7 @@ else if (isOperator(currentChar + ""))
132134 {
133135 currentChar = currentChar == '×' ? '*' : currentChar == '÷' ? '/' : currentChar ;
134136 while (!operators .isEmpty () && !operators .peek ().equals ("(" ) && getOperatorPrecedence (operators .peek ()) >= getOperatorPrecedence (currentChar + "" ) && currentChar != '^' )
135- performStacking (output , operators .pop (), useRadians );
137+ performStacking (output , operators .pop (), configurationBuilder . isUseRadiansEnabled () );
136138 operators .push (currentChar + "" );
137139 }
138140 }
@@ -199,7 +201,7 @@ else if (!isPartOfANumber(currentChar))
199201 output .push (new BigDecimal (numberStr ));
200202 numberBuilder .setLength (0 );
201203 while (!operators .isEmpty () && (isUnaryOperator (operators .peek ()) && !operators .peek ().equals ("u-" )))
202- performStacking (output , operators .pop (), useRadians );
204+ performStacking (output , operators .pop (), configurationBuilder . isUseRadiansEnabled () );
203205 }
204206 else
205207 throw new SyntaxErrorException ("Found an invalid number \" " + numberStr + "\" while parsing the given expression" );
@@ -212,12 +214,12 @@ else if (!isPartOfANumber(currentChar))
212214
213215 if (output .isEmpty ()) return null ;
214216
215- if (balanceParentheses && openParenthesesCount > 0 )
217+ if (configurationBuilder . isBalanceParenthesesEnabled () && openParenthesesCount > 0 )
216218 {
217219 while (openParenthesesCount -- > 0 )
218220 {
219221 while (!operators .isEmpty () && !operators .peek ().equals ("(" ))
220- performStacking (output , operators .pop (), useRadians );
222+ performStacking (output , operators .pop (), configurationBuilder . isUseRadiansEnabled () );
221223 if (operators .isEmpty () || !operators .peek ().equals ("(" ))
222224 throw new UnbalancedParenthesesException ("Failed to balance the parentheses in the given expression" );
223225 operators .pop ();
@@ -227,12 +229,12 @@ else if (!isPartOfANumber(currentChar))
227229 while (!operators .isEmpty ())
228230 {
229231 String operator = operators .pop ();
230- if (operator .equals ("(" ) && !balanceParentheses )
232+ if (operator .equals ("(" ) && !configurationBuilder . isBalanceParenthesesEnabled () )
231233 throw new UnbalancedParenthesesException ("Parentheses are not well placed" );
232234 else
233- performStacking (output , operator , useRadians );
235+ performStacking (output , operator , configurationBuilder . isUseRadiansEnabled () );
234236 }
235- return formatResult (output .pop (), precision );
237+ return formatResult (output .pop (), configurationBuilder . getPrecision () );
236238 }
237239
238240 /**
0 commit comments