Simple Equation Solver

Please support our Java advertiser: Programming Forums - DaniWeb Sister Site
Alex Edwards Alex Edwards is offline Offline Nov 3rd, 2008, 9:32 am |
1
Solves simple string-based expressions.

Currently only supports integers, but can easily be expanded to support float-types.
Quick reply to this message  
Java Syntax
  1. import java.util.*;
  2. /**
  3.  * Utility class for solving equations
  4.  */
  5. public class EquationSolver{
  6.  
  7. public static void main(String... args){
  8. System.out.println(EquationSolver.solve("5 + 3 * (8 - 4)"));
  9. System.out.println();
  10. System.out.println(EquationSolver.solve("12 / (3 * 4) + 5"));
  11.  
  12. }
  13.  
  14. private static String doOperation(String lhs, char operator, String rhs){
  15. switch(operator){
  16. case '^':
  17. return "" + (int)Math.pow( (int)Integer.parseInt(lhs), (int)Integer.parseInt(rhs) );
  18. case '*':
  19. return "" + (Integer.parseInt(lhs) * Integer.parseInt(rhs));
  20. case '/':
  21. return "" + (Integer.parseInt(lhs) / Integer.parseInt(rhs));
  22. case '+':
  23. return "" + (Integer.parseInt(lhs) + Integer.parseInt(rhs));
  24. case '-':
  25. return "" + (Integer.parseInt(lhs) - Integer.parseInt(rhs));
  26. }
  27. return "";
  28. }
  29.  
  30. /**
  31. * Contains an expression that exists within parenthesis
  32. * i.e., (5+3), (6 + 2), etc.
  33. *
  34. * If a set of paranethesis exists within the expression, it must be resolved
  35. * by using another expression object to solve the inner expression.
  36. * i.e., (5 + 3 - 2 + (8 * 7) ) would first result in an ExpressionNode consisting of
  37. * a call to another expression to Solve the inner expression
  38. */
  39. private class ExpressionNode{
  40.  
  41. String expression = "";
  42.  
  43. /**
  44. * Accepts a String argument as an expression
  45. */
  46. ExpressionNode(String arg){
  47.  
  48. /*
  49. * LOGIC:
  50. * -Set this object's globally scoped String to the newly corrected one.
  51. */
  52. expression = correctedString(arg);
  53. }
  54.  
  55. /**
  56. * Returns a corrected version of the String, which is one that
  57. * has its first and last paranthesis removed.
  58. */
  59. private String correctedString(String arg){
  60.  
  61. // A Mutable String
  62. StringBuilder sb = new StringBuilder();
  63.  
  64. /*
  65. * LOGIC:
  66. * -For every character in arg
  67. * -If a left paranthesis character is found and it is the first one found
  68. * -set foundFirst to true and do not add that character to the StringBuilder
  69. * -Else
  70. * -append to the StringBuilder the current character
  71. *
  72. * -make arg point to a reversed version of the StringBuilder's String
  73. * -clear the StringBuilder for reuse
  74. * -reset foundFirst (since we're planning on trying again)
  75. *
  76. * -For every character in arg
  77. * -If a right paranthesis character is found and it is the first one found
  78. * -set foundFirst to true and do not add that character to the StringBuilder
  79. * -Else
  80. * -append to the StringBuilder the current character
  81. *
  82. * -make arg point to a reversed version of the StringBuilder's String
  83. * -return arg
  84. */
  85. boolean foundFirst = false;
  86. for(int i = 0; i < arg.length(); i++)
  87. if(foundFirst == false && arg.charAt(i) == '(')
  88. foundFirst = true;
  89. else sb.append(arg.charAt(i));
  90.  
  91. arg = new StringBuilder(sb.reverse()).toString();
  92. sb.delete(0, sb.length());
  93.  
  94. foundFirst = false;
  95. for(int i = 0; i < arg.length(); i++)
  96. if(foundFirst == false && arg.charAt(i) == ')')
  97. foundFirst = true;
  98. else sb.append(arg.charAt(i));
  99.  
  100. return arg = new StringBuilder(sb.reverse()).toString();
  101. }
  102.  
  103. //private String
  104.  
  105. /**
  106. * Returns the result of the calculated ExpressionNode.
  107. * If another expression is found within this one,
  108. * a new ExpressionNode will be created and will solve
  109. * the inner expression.
  110. */
  111. public String toString(){
  112.  
  113. /*
  114. * LOGIC:
  115. * -Create a finalExpression for a String and initialize it with an empty String
  116. * -For every character in the expression
  117. * -If a left paranthesis is encountered (denoting an inner expression)
  118. * -Create a placeholder for a String and initialize it with a left paranthesis character
  119. * -initialize valuesCounted as an int with the value of 1, denoting that we have at least 1 value
  120. * -For every character, starting at that parenthesis (not including that paranthesis), until valuesCounted is zero
  121. * -If the character is a left paranthesis
  122. * -increment valuesCounted and add the left paranthesis to the placeholder
  123. * -Else If the character is a right paranthesis
  124. * -decrement valuesCounted and add the right paranthesis to the nested placeholder
  125. * -Create an ExpressionNode for the placeHolder String
  126. * -add the toString of the ExpressionNode to the finalExpression String
  127. * -increment i by the length - 1 of the placeHolder
  128. * -Else
  129. * -add the character to the finalExpression String
  130. *
  131. * -Create a resizable array named totalNumbers to store the numbers in the expression
  132. * -Create a resizable array named totalOperations to store the operators in the expression
  133. *
  134. * -For every character in finalExpression
  135. * -If the character encountered is between characters '1' and '9'
  136. * -store the current value of i into storedNumber [???]
  137. * -Create a temp String to collect characters for the number
  138. * -For every number character in the number set selected
  139. * -Concatenate that number to the temp String
  140. * -add the temp String to the ArrayList totalNumbers
  141. * -advance i by (the length of the temp String - 1)
  142. * -Else if the character encountered is '*', '-', '+', '/', '^'
  143. * -store the character in the ArrayList totalOperations
  144. *
  145. * -Create a temp String to hold the final result
  146. *
  147. * -For every Character object in totalOperations, using an int named i as a means to track values
  148. * -If the Character object in totalOperations, located at i, is equal to ^
  149. * -perform the power operation of the Integer form of the String at location i
  150. * of the totalNumbers array with the Integer form of the String at location i + 1
  151. * of the totalNumbers array and store the result in the temp String.
  152. * -set the value of the Character object in totalOperations at i to null
  153. * -set the value of the String object in totalNumbers at i + 1 to null
  154. * -set the value of the String object in totalNumbers at i to be that of the temp String
  155. * -trim the totalOperations array to a new size, so the null value is removed
  156. * -trim the totalNumbers array to a new size, so the null value is removed
  157. * -decrement i
  158. *
  159. * -clear the temp String
  160. * -For every Character object in totalOperations, using an int named i as a means to track values
  161. * -If the Character object in totalOperations, located at i, is equal to * or /
  162. * -perform the necessary operation of the Integer form of the String at location i
  163. * of the totalNumbers array with the Integer form of the String at location i + 1
  164. * of the totalNumbers array and store the result in the temp String.
  165. * -set the value of the Character object in totalOperations at i to null
  166. * -set the value of the String object in totalNumbers at i + 1 to null
  167. * -set the value of the String object in totalNumbers at i to be that of the temp String
  168. * -trim the totalOperations array to a new size, so the null value is removed
  169. * -trim the totalNumbers array to a new size, so the null value is removed
  170. * -decrement i
  171. *
  172. * -clear the temp String
  173. * -For every Character object in totalOperations, using an int named i as a means to track values
  174. * -If the Character object in totalOperations, located at i, is equal to + or -
  175. * -Create a temp String to hold the final result
  176. * -perform the necessary operation of the Integer form of the String at location i
  177. * of the totalNumbers array with the Integer form of the String at location i + 1
  178. * of the totalNumbers array and store the result in the temp String.
  179. * -set the value of the Character object in totalOperations at i to null
  180. * -set the value of the String object in totalNumbers at i + 1 to null
  181. * -set the value of the String object in totalNumbers at i to be that of the temp String
  182. * -decrement i
  183. *
  184. * -return the first element of totalNumbers
  185. */
  186.  
  187. String finalExpression = "";
  188.  
  189. for(int i = 0; i < expression.length(); i++){
  190. if(expression.charAt(i) == '('){
  191. String placeHolder = "(";
  192. int valuesCounted = 1;
  193.  
  194. for(int j = i + 1; valuesCounted != 0; j++){
  195. if(expression.charAt(j) == '(')
  196. valuesCounted++;
  197. else if(expression.charAt(j) == ')')
  198. valuesCounted--;
  199.  
  200. placeHolder += "" + expression.charAt(j);
  201. }
  202.  
  203. String evaluatedString = new ExpressionNode(placeHolder).toString();
  204. finalExpression += evaluatedString;
  205. i+= (placeHolder.length() - 1);
  206. }else{
  207. finalExpression += "" + expression.charAt(i);
  208. }
  209. }
  210.  
  211. ArrayList<String> totalNumbers = new ArrayList<String>(0);
  212. ArrayList<Character> totalOperations = new ArrayList<Character>(0);
  213. System.out.println(finalExpression);
  214.  
  215. for(int i = 0; i < finalExpression.length(); i++){
  216. if((int)finalExpression.charAt(i) >= (int)'1' && (int)finalExpression.charAt(i) <= (int)'9'){
  217. String temp = "";
  218. for(int j = i; j < finalExpression.length(); j++){
  219. if(finalExpression.charAt(j) >= '1' && finalExpression.charAt(j) <= '9'){
  220. temp += "" + finalExpression.charAt(j);
  221. }else break;
  222. }
  223. totalNumbers.add(temp);
  224. i += temp.length() == 0 ? 0 : (temp.length() - 1);
  225. }else if(finalExpression.charAt(i) == '*'
  226. || finalExpression.charAt(i) == '/'
  227. || finalExpression.charAt(i) == '^'
  228. || finalExpression.charAt(i) == '+'
  229. || finalExpression.charAt(i) == '-'
  230. ){
  231. totalOperations.add(new Character(finalExpression.charAt(i)));
  232. }
  233. }
  234.  
  235. String result = "";
  236.  
  237. for(int i = 0; i < totalOperations.size(); i++){
  238. if(totalOperations.get(i).equals(new Character('^'))){
  239. result = doOperation(totalNumbers.get(i), (char)totalOperations.get(i), totalNumbers.get(i + 1));
  240. totalOperations.set(i, null);
  241. totalNumbers.set(i, result);
  242. totalNumbers.set(i + 1, null);
  243. totalOperations.remove(i);
  244. totalNumbers.remove(i + 1);
  245. i--;
  246. }
  247. }
  248.  
  249. for(int i = 0; i < totalOperations.size(); i++){
  250. if(totalOperations.get(i).equals(new Character('*'))
  251. || totalOperations.get(i).equals(new Character('/'))){
  252. result = doOperation(totalNumbers.get(i), (char)totalOperations.get(i), totalNumbers.get(i + 1));
  253. totalOperations.set(i, null);
  254. totalNumbers.set(i, result);
  255. totalNumbers.set(i + 1, null);
  256. totalOperations.remove(i);
  257. totalNumbers.remove(i + 1);
  258. i--;
  259.  
  260. }
  261. }
  262.  
  263. for(int i = 0; i < totalOperations.size(); i++){
  264. if(totalOperations.get(i).equals(new Character('+'))
  265. || totalOperations.get(i).equals(new Character('-'))){
  266. result = doOperation(totalNumbers.get(i), (char)totalOperations.get(i), totalNumbers.get(i + 1));
  267. totalOperations.set(i, null);
  268. totalNumbers.set(i, result);
  269. totalNumbers.set(i + 1, null);
  270. totalOperations.remove(i);
  271. totalNumbers.remove(i + 1);
  272. i--;
  273. }
  274. }
  275.  
  276. return totalNumbers.get(0);
  277. }
  278. }
  279.  
  280. private static void sleep(int millis){
  281. try{
  282. Thread.sleep(millis);
  283. }catch(Exception e){}
  284. }
  285.  
  286. /**
  287. * Checks to see if the expression is solvable or not.
  288. */
  289. private static boolean isSolvable(String eq){
  290.  
  291. int paranthesisCount = 0;
  292.  
  293. /*
  294. * LOGIC:
  295. * -For all characters in the String eq
  296. * -If a character encountered is equal to a left paranthesis
  297. * -Increment the paranthesis count
  298. * -Else If a character encountered is equal to a right paranthesis
  299. * -Decrement the paranthesis count
  300. * -return true if the count is zero, otherwise return false, and the reasoning
  301. * for this is because if the paranthesis in the String do not match, the expression
  302. * cannot be solved.
  303. */
  304. for(char element : eq.toCharArray()){
  305. if(element == '(')
  306. paranthesisCount++;
  307. else if(element == ')')
  308. paranthesisCount--;
  309. }
  310. return paranthesisCount == 0;
  311. }
  312.  
  313. public static String solve(String eq){
  314. if(isSolvable(eq)){
  315. EquationSolver es = new EquationSolver();
  316. return es.new ExpressionNode(eq).toString();
  317. }else return "";
  318. }
  319.  
  320. }
0
Alex Edwards Alex Edwards is offline Offline | Nov 3rd, 2008
Darn I just noticed it doesn't handle negatives well... @_@

This can be easily modified by simply changing subtraction to plus-negative values and only doing sums of values.
 
0
Alex Edwards Alex Edwards is offline Offline | Nov 3rd, 2008
A version that works with negatives--

  1. import java.util.*;
  2. import java.io.*;
  3. /**
  4.  * Utility class for solving equations
  5.  */
  6. public class EquationSolver{
  7.  
  8. public static void main(String... args){
  9. System.out.println(EquationSolver.solve("5 + 3 * (8 - 4)"));
  10. System.out.println();
  11. System.out.println(EquationSolver.solve("12 / (3 * 4) + 5"));
  12. System.out.println();
  13. BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
  14.  
  15. System.out.print("Enter an equation you would like to solve: ");
  16. try{
  17. System.out.println( EquationSolver.solve(br.readLine()) );
  18. }catch(Exception e){
  19.  
  20. }
  21. }
  22.  
  23. private static String doOperation(String lhs, char operator, String rhs){
  24. switch(operator){
  25. case '^':
  26. return "" + (int)Math.pow( (int)Integer.parseInt(lhs), (int)Integer.parseInt(rhs) );
  27. case '*':
  28. return "" + (Integer.parseInt(lhs) * Integer.parseInt(rhs));
  29. case '/':
  30. return "" + (Integer.parseInt(lhs) / Integer.parseInt(rhs));
  31. case '+':
  32. return "" + (Integer.parseInt(lhs) + Integer.parseInt(rhs));
  33. case '-':
  34. return "" + (Integer.parseInt(lhs) - Integer.parseInt(rhs));
  35. }
  36. return "";
  37. }
  38.  
  39. /**
  40. * Contains an expression that exists within parenthesis
  41. * i.e., (5+3), (6 + 2), etc.
  42. *
  43. * If a set of paranethesis exists within the expression, it must be resolved
  44. * by using another expression object to solve the inner expression.
  45. * i.e., (5 + 3 - 2 + (8 * 7) ) would first result in an ExpressionNode consisting of
  46. * a call to another expression to Solve the inner expression
  47. */
  48. private class ExpressionNode{
  49.  
  50. String expression = "";
  51.  
  52. /**
  53. * Accepts a String argument as an expression
  54. */
  55. ExpressionNode(String arg){
  56.  
  57. /*
  58. * LOGIC:
  59. * -Set this object's globally scoped String to the newly corrected one.
  60. */
  61. expression = correctedString(arg);
  62. }
  63.  
  64. /**
  65. * Returns a corrected version of the String, which is one that
  66. * has its first and last paranthesis removed.
  67. */
  68. private String correctedString(String arg){
  69.  
  70. // A Mutable String
  71. StringBuilder sb = new StringBuilder();
  72.  
  73. /*
  74. * LOGIC:
  75. * -For every character in arg
  76. * -If a left paranthesis character is found and it is the first one found
  77. * -set foundFirst to true and do not add that character to the StringBuilder
  78. * -Else
  79. * -append to the StringBuilder the current character
  80. *
  81. * -make arg point to a reversed version of the StringBuilder's String
  82. * -clear the StringBuilder for reuse
  83. * -reset foundFirst (since we're planning on trying again)
  84. *
  85. * -For every character in arg
  86. * -If a right paranthesis character is found and it is the first one found
  87. * -set foundFirst to true and do not add that character to the StringBuilder
  88. * -Else
  89. * -append to the StringBuilder the current character
  90. *
  91. * -make arg point to a reversed version of the StringBuilder's String
  92. * -return arg
  93. */
  94. boolean foundFirst = false;
  95. for(int i = 0; i < arg.length(); i++)
  96. if(foundFirst == false && arg.charAt(i) == '(')
  97. foundFirst = true;
  98. else sb.append(arg.charAt(i));
  99.  
  100. arg = new StringBuilder(sb.reverse()).toString();
  101. sb.delete(0, sb.length());
  102.  
  103. foundFirst = false;
  104. for(int i = 0; i < arg.length(); i++)
  105. if(foundFirst == false && arg.charAt(i) == ')')
  106. foundFirst = true;
  107. else sb.append(arg.charAt(i));
  108.  
  109. return arg = new StringBuilder(sb.reverse()).toString();
  110. }
  111.  
  112. //private String
  113.  
  114. /**
  115. * Returns the result of the calculated ExpressionNode.
  116. * If another expression is found within this one,
  117. * a new ExpressionNode will be created and will solve
  118. * the inner expression.
  119. */
  120. public String toString(){
  121.  
  122. /*
  123. * LOGIC:
  124. * -Create a finalExpression for a String and initialize it with an empty String
  125. * -For every character in the expression
  126. * -If a left paranthesis is encountered (denoting an inner expression)
  127. * -Create a placeholder for a String and initialize it with a left paranthesis character
  128. * -initialize valuesCounted as an int with the value of 1, denoting that we have at least 1 value
  129. * -For every character, starting at that parenthesis (not including that paranthesis), until valuesCounted is zero
  130. * -If the character is a left paranthesis
  131. * -increment valuesCounted and add the left paranthesis to the placeholder
  132. * -Else If the character is a right paranthesis
  133. * -decrement valuesCounted and add the right paranthesis to the nested placeholder
  134. * -Create an ExpressionNode for the placeHolder String
  135. * -add the toString of the ExpressionNode to the finalExpression String
  136. * -increment i by the length - 1 of the placeHolder
  137. * -Else if the character is a '-' character
  138. * -append a + to the finalExpression String
  139. * -append a - to the finalExpression String
  140. * -Else
  141. * -add the character to the finalExpression String
  142. *
  143. * -Create a resizable array named totalNumbers to store the numbers in the expression
  144. * -Create a resizable array named totalOperations to store the operators in the expression
  145. *
  146. * -Create a temporary String for the compressed version of the finalExpression
  147. * -For every character in the finalExpression
  148. * -If the character is not equal to a space character
  149. * -append the character to the temporary String
  150. * -make finalExpression point to the temporary String
  151. *
  152. * -For every character in finalExpression
  153. * -If the character encountered is between characters '1' and '9' or is a minus sign '-'
  154. * -store the current value of i into storedNumber [???]
  155. * -Create a temp String to collect characters for the number
  156. * -For every number character in the number set selected
  157. * -Concatenate that number to the temp String
  158. * -add the temp String to the ArrayList totalNumbers
  159. * -advance i by (the length of the temp String - 1)
  160. * -Else if the character encountered is '*', '+', '/', '^'
  161. * -store the character in the ArrayList totalOperations
  162. *
  163. * -Create a temp String to hold the final result
  164. *
  165. * -For every Character object in totalOperations, using an int named i as a means to track values
  166. * -If the Character object in totalOperations, located at i, is equal to ^
  167. * -perform the power operation of the Integer form of the String at location i
  168. * of the totalNumbers array with the Integer form of the String at location i + 1
  169. * of the totalNumbers array and store the result in the temp String.
  170. * -set the value of the Character object in totalOperations at i to null
  171. * -set the value of the String object in totalNumbers at i + 1 to null
  172. * -set the value of the String object in totalNumbers at i to be that of the temp String
  173. * -trim the totalOperations array to a new size, so the null value is removed
  174. * -trim the totalNumbers array to a new size, so the null value is removed
  175. * -decrement i
  176. *
  177. * -clear the temp String
  178. * -For every Character object in totalOperations, using an int named i as a means to track values
  179. * -If the Character object in totalOperations, located at i, is equal to * or /
  180. * -perform the necessary operation of the Integer form of the String at location i
  181. * of the totalNumbers array with the Integer form of the String at location i + 1
  182. * of the totalNumbers array and store the result in the temp String.
  183. * -set the value of the Character object in totalOperations at i to null
  184. * -set the value of the String object in totalNumbers at i + 1 to null
  185. * -set the value of the String object in totalNumbers at i to be that of the temp String
  186. * -trim the totalOperations array to a new size, so the null value is removed
  187. * -trim the totalNumbers array to a new size, so the null value is removed
  188. * -decrement i
  189. *
  190. * -clear the temp String
  191. * -For every Character object in totalOperations, using an int named i as a means to track values
  192. * -If the Character object in totalOperations, located at i, is equal to +
  193. * -Create a temp String to hold the final result
  194. * -perform the necessary operation of the Integer form of the String at location i
  195. * of the totalNumbers array with the Integer form of the String at location i + 1
  196. * of the totalNumbers array and store the result in the temp String.
  197. * -set the value of the Character object in totalOperations at i to null
  198. * -set the value of the String object in totalNumbers at i + 1 to null
  199. * -set the value of the String object in totalNumbers at i to be that of the temp String
  200. * -decrement i
  201. *
  202. * -return the first element of totalNumbers
  203. */
  204.  
  205. String finalExpression = "";
  206. boolean operatorEncountered = true;
  207. for(int i = 0; i < expression.length(); i++){
  208. if(expression.charAt(i) == '('){
  209. String placeHolder = "(";
  210. int valuesCounted = 1;
  211.  
  212. for(int j = i + 1; valuesCounted != 0; j++){
  213. if(expression.charAt(j) == '(')
  214. valuesCounted++;
  215. else if(expression.charAt(j) == ')')
  216. valuesCounted--;
  217.  
  218. placeHolder += "" + expression.charAt(j);
  219. }
  220.  
  221. String evaluatedString = new ExpressionNode(placeHolder).toString();
  222. finalExpression += evaluatedString;
  223. i+= (placeHolder.length() - 1);
  224. }else{
  225. if(expression.charAt(i) == '-' && operatorEncountered == false)
  226. finalExpression += '+';
  227. finalExpression += "" + expression.charAt(i);
  228. if((expression.charAt(i) == '+' || expression.charAt(i) == '/' || expression.charAt(i) == '^'
  229. || expression.charAt(i) == '*'))
  230. operatorEncountered = true;
  231. else if(expression.charAt(i) != ' ')
  232. operatorEncountered = false;
  233. }
  234. }
  235.  
  236. String myTempString = "";
  237.  
  238. for(int i = 0; i < finalExpression.length(); i++){
  239. if(finalExpression.charAt(i) != ' '){
  240. myTempString += "" + finalExpression.charAt(i);
  241. }
  242. }
  243.  
  244. finalExpression = myTempString;
  245.  
  246. ArrayList<String> totalNumbers = new ArrayList<String>(0);
  247. ArrayList<Character> totalOperations = new ArrayList<Character>(0);
  248. System.out.println(finalExpression);
  249.  
  250. for(int i = 0; i < finalExpression.length(); i++){
  251. if((int)finalExpression.charAt(i) >= (int)'1' && (int)finalExpression.charAt(i) <= (int)'9'
  252. || finalExpression.charAt(i) == '-'){
  253. String temp = "";
  254. for(int j = i; j < finalExpression.length(); j++){
  255. if(finalExpression.charAt(j) >= '1' && finalExpression.charAt(j) <= '9'
  256. || finalExpression.charAt(j) == '-'){
  257. temp += "" + finalExpression.charAt(j);
  258. }else break;
  259. }
  260. totalNumbers.add(temp);
  261. i += temp.length() == 0 ? 0 : (temp.length() - 1);
  262. }else if(finalExpression.charAt(i) == '*'
  263. || finalExpression.charAt(i) == '/'
  264. || finalExpression.charAt(i) == '^'
  265. || finalExpression.charAt(i) == '+'
  266. ){
  267. totalOperations.add(new Character(finalExpression.charAt(i)));
  268. }
  269. }
  270.  
  271. String result = "";
  272.  
  273. for(int i = 0; i < totalOperations.size(); i++){
  274. if(totalOperations.get(i).equals(new Character('^'))){
  275. result = doOperation(totalNumbers.get(i), (char)totalOperations.get(i), totalNumbers.get(i + 1));
  276. totalOperations.set(i, null);
  277. totalNumbers.set(i, result);
  278. totalNumbers.set(i + 1, null);
  279. totalOperations.remove(i);
  280. totalNumbers.remove(i + 1);
  281. i--;
  282. }
  283. }
  284.  
  285. for(int i = 0; i < totalOperations.size(); i++){
  286. if(totalOperations.get(i).equals(new Character('*'))
  287. || totalOperations.get(i).equals(new Character('/'))){
  288. result = doOperation(totalNumbers.get(i), (char)totalOperations.get(i), totalNumbers.get(i + 1));
  289. totalOperations.set(i, null);
  290. totalNumbers.set(i, result);
  291. totalNumbers.set(i + 1, null);
  292. totalOperations.remove(i);
  293. totalNumbers.remove(i + 1);
  294. i--;
  295.  
  296. }
  297. }
  298.  
  299. for(int i = 0; i < totalOperations.size(); i++){
  300. if(totalOperations.get(i).equals(new Character('+'))){
  301. result = doOperation(totalNumbers.get(i), (char)totalOperations.get(i), totalNumbers.get(i + 1));
  302. totalOperations.set(i, null);
  303. totalNumbers.set(i, result);
  304. totalNumbers.set(i + 1, null);
  305. totalOperations.remove(i);
  306. totalNumbers.remove(i + 1);
  307. i--;
  308. }
  309. }
  310.  
  311. return totalNumbers.get(0);
  312. }
  313. }
  314.  
  315. private static void sleep(int millis){
  316. try{
  317. Thread.sleep(millis);
  318. }catch(Exception e){}
  319. }
  320.  
  321. /**
  322. * Checks to see if the expression is solvable or not.
  323. */
  324. private static boolean isSolvable(String eq){
  325.  
  326. int paranthesisCount = 0;
  327.  
  328. /*
  329. * LOGIC:
  330. * -For all characters in the String eq
  331. * -If a character encountered is equal to a left paranthesis
  332. * -Increment the paranthesis count
  333. * -Else If a character encountered is equal to a right paranthesis
  334. * -Decrement the paranthesis count
  335. * -return true if the count is zero, otherwise return false, and the reasoning
  336. * for this is because if the paranthesis in the String do not match, the expression
  337. * cannot be solved.
  338. */
  339. for(char element : eq.toCharArray()){
  340. if(element == '(')
  341. paranthesisCount++;
  342. else if(element == ')')
  343. paranthesisCount--;
  344. }
  345. return paranthesisCount == 0;
  346. }
  347.  
  348. public static String solve(String eq){
  349. if(isSolvable(eq)){
  350. EquationSolver es = new EquationSolver();
  351. return es.new ExpressionNode(eq).toString();
  352. }else return "";
  353. }
  354.  
  355. }
 
0
Alex Edwards Alex Edwards is offline Offline | Nov 3rd, 2008
5+3*8+-4
25
12/3*4+5
21

Enter an equation you would like to solve: ( 9 * (2 ^ (-3 + 5) * 8 - 3) )
-3+5
2^2*8+-3
9*29
261
Press any key to continue...
 
0
Alex Edwards Alex Edwards is offline Offline | Nov 4th, 2008
This program treats zeros properly--

  1. import java.util.*;
  2. import java.io.*;
  3. /**
  4.  * Utility class for solving equations
  5.  */
  6. public class EquationSolver{
  7.  
  8. public static void main(String... args){
  9. System.out.println(EquationSolver.solve("5 + 3 * (8 - 4)"));
  10. System.out.println();
  11. System.out.println(EquationSolver.solve("12 / (3 * 4) + 5"));
  12. System.out.println();
  13. BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
  14.  
  15. while(true){
  16. System.out.print("Enter an equation you would like to solve: ");
  17. try{
  18. System.out.println( EquationSolver.solve(br.readLine()) );
  19. }catch(Exception e){
  20.  
  21. }
  22. }
  23. }
  24.  
  25. private static String doOperation(String lhs, char operator, String rhs){
  26. switch(operator){
  27. case '^':
  28. return "" + (int)Math.pow( (int)Integer.parseInt(lhs), (int)Integer.parseInt(rhs) );
  29. case '*':
  30. return "" + (Integer.parseInt(lhs) * Integer.parseInt(rhs));
  31. case '/':
  32. return "" + (Integer.parseInt(lhs) / Integer.parseInt(rhs));
  33. case '+':
  34. return "" + (Integer.parseInt(lhs) + Integer.parseInt(rhs));
  35. case '-':
  36. return "" + (Integer.parseInt(lhs) - Integer.parseInt(rhs));
  37. }
  38. return "";
  39. }
  40.  
  41. /**
  42. * Contains an expression that exists within parenthesis
  43. * i.e., (5+3), (6 + 2), etc.
  44. *
  45. * If a set of paranethesis exists within the expression, it must be resolved
  46. * by using another expression object to solve the inner expression.
  47. * i.e., (5 + 3 - 2 + (8 * 7) ) would first result in an ExpressionNode consisting of
  48. * a call to another expression to Solve the inner expression
  49. */
  50. private class ExpressionNode{
  51.  
  52. String expression = "";
  53.  
  54. /**
  55. * Accepts a String argument as an expression
  56. */
  57. ExpressionNode(String arg){
  58.  
  59. /*
  60. * LOGIC:
  61. * -Set this object's globally scoped String to the newly corrected one.
  62. */
  63. expression = correctedString(arg);
  64. }
  65.  
  66. /**
  67. * Returns a corrected version of the String, which is one that
  68. * has its first and last paranthesis removed.
  69. */
  70. private String correctedString(String arg){
  71.  
  72. // A Mutable String
  73. StringBuilder sb = new StringBuilder();
  74.  
  75. /*
  76. * LOGIC:
  77. * -For every character in arg
  78. * -If a left paranthesis character is found and it is the first one found
  79. * -set foundFirst to true and do not add that character to the StringBuilder
  80. * -Else
  81. * -append to the StringBuilder the current character
  82. *
  83. * -make arg point to a reversed version of the StringBuilder's String
  84. * -clear the StringBuilder for reuse
  85. * -reset foundFirst (since we're planning on trying again)
  86. *
  87. * -For every character in arg
  88. * -If a right paranthesis character is found and it is the first one found
  89. * -set foundFirst to true and do not add that character to the StringBuilder
  90. * -Else
  91. * -append to the StringBuilder the current character
  92. *
  93. * -make arg point to a reversed version of the StringBuilder's String
  94. * -return arg
  95. */
  96. boolean foundFirst = false;
  97. for(int i = 0; i < arg.length(); i++)
  98. if(foundFirst == false && arg.charAt(i) == '(')
  99. foundFirst = true;
  100. else sb.append(arg.charAt(i));
  101.  
  102. arg = new StringBuilder(sb.reverse()).toString();
  103. sb.delete(0, sb.length());
  104.  
  105. foundFirst = false;
  106. for(int i = 0; i < arg.length(); i++)
  107. if(foundFirst == false && arg.charAt(i) == ')')
  108. foundFirst = true;
  109. else sb.append(arg.charAt(i));
  110.  
  111. return arg = new StringBuilder(sb.reverse()).toString();
  112. }
  113.  
  114. //private String
  115.  
  116. /**
  117. * Returns the result of the calculated ExpressionNode.
  118. * If another expression is found within this one,
  119. * a new ExpressionNode will be created and will solve
  120. * the inner expression.
  121. */
  122. public String toString(){
  123.  
  124. /*
  125. * LOGIC:
  126. * -Create a finalExpression for a String and initialize it with an empty String
  127. * -For every character in the expression
  128. * -If a left paranthesis is encountered (denoting an inner expression)
  129. * -Create a placeholder for a String and initialize it with a left paranthesis character
  130. * -initialize valuesCounted as an int with the value of 1, denoting that we have at least 1 value
  131. * -For every character, starting at that parenthesis (not including that paranthesis), until valuesCounted is zero
  132. * -If the character is a left paranthesis
  133. * -increment valuesCounted and add the left paranthesis to the placeholder
  134. * -Else If the character is a right paranthesis
  135. * -decrement valuesCounted and add the right paranthesis to the nested placeholder
  136. * -Create an ExpressionNode for the placeHolder String
  137. * -add the toString of the ExpressionNode to the finalExpression String
  138. * -increment i by the length - 1 of the placeHolder
  139. * -Else if the character is a '-' character
  140. * -append a + to the finalExpression String
  141. * -append a - to the finalExpression String
  142. * -Else
  143. * -add the character to the finalExpression String
  144. *
  145. * -Create a resizable array named totalNumbers to store the numbers in the expression
  146. * -Create a resizable array named totalOperations to store the operators in the expression
  147. *
  148. * -Create a temporary String for the compressed version of the finalExpression
  149. * -For every character in the finalExpression
  150. * -If the character is not equal to a space character
  151. * -append the character to the temporary String
  152. * -make finalExpression point to the temporary String
  153. *
  154. * -For every character in finalExpression
  155. * -If the character encountered is between characters '1' and '9' or is a minus sign '-'
  156. * -store the current value of i into storedNumber [???]
  157. * -Create a temp String to collect characters for the number
  158. * -For every number character in the number set selected
  159. * -Concatenate that number to the temp String
  160. * -add the temp String to the ArrayList totalNumbers
  161. * -advance i by (the length of the temp String - 1)
  162. * -Else if the character encountered is '*', '+', '/', '^'
  163. * -store the character in the ArrayList totalOperations
  164. *
  165. * -Create a temp String to hold the final result
  166. *
  167. * -For every Character object in totalOperations, using an int named i as a means to track values
  168. * -If the Character object in totalOperations, located at i, is equal to ^
  169. * -perform the power operation of the Integer form of the String at location i
  170. * of the totalNumbers array with the Integer form of the String at location i + 1
  171. * of the totalNumbers array and store the result in the temp String.
  172. * -set the value of the Character object in totalOperations at i to null
  173. * -set the value of the String object in totalNumbers at i + 1 to null
  174. * -set the value of the String object in totalNumbers at i to be that of the temp String
  175. * -trim the totalOperations array to a new size, so the null value is removed
  176. * -trim the totalNumbers array to a new size, so the null value is removed
  177. * -decrement i
  178. *
  179. * -clear the temp String
  180. * -For every Character object in totalOperations, using an int named i as a means to track values
  181. * -If the Character object in totalOperations, located at i, is equal to * or /
  182. * -perform the necessary operation of the Integer form of the String at location i
  183. * of the totalNumbers array with the Integer form of the String at location i + 1
  184. * of the totalNumbers array and store the result in the temp String.
  185. * -set the value of the Character object in totalOperations at i to null
  186. * -set the value of the String object in totalNumbers at i + 1 to null
  187. * -set the value of the String object in totalNumbers at i to be that of the temp String
  188. * -trim the totalOperations array to a new size, so the null value is removed
  189. * -trim the totalNumbers array to a new size, so the null value is removed
  190. * -decrement i
  191. *
  192. * -clear the temp String
  193. * -For every Character object in totalOperations, using an int named i as a means to track values
  194. * -If the Character object in totalOperations, located at i, is equal to +
  195. * -Create a temp String to hold the final result
  196. * -perform the necessary operation of the Integer form of the String at location i
  197. * of the totalNumbers array with the Integer form of the String at location i + 1
  198. * of the totalNumbers array and store the result in the temp String.
  199. * -set the value of the Character object in totalOperations at i to null
  200. * -set the value of the String object in totalNumbers at i + 1 to null
  201. * -set the value of the String object in totalNumbers at i to be that of the temp String
  202. * -decrement i
  203. *
  204. * -return the first element of totalNumbers
  205. */
  206.  
  207. String finalExpression = "";
  208. boolean operatorEncountered = true;
  209. for(int i = 0; i < expression.length(); i++){
  210. if(expression.charAt(i) == '('){
  211. String placeHolder = "(";
  212. int valuesCounted = 1;
  213.  
  214. for(int j = i + 1; valuesCounted != 0; j++){
  215. if(expression.charAt(j) == '(')
  216. valuesCounted++;
  217. else if(expression.charAt(j) == ')')
  218. valuesCounted--;
  219.  
  220. placeHolder += "" + expression.charAt(j);
  221. }
  222.  
  223. String evaluatedString = new ExpressionNode(placeHolder).toString();
  224. finalExpression += evaluatedString;
  225. i+= (placeHolder.length() - 1);
  226. }else{
  227. if(expression.charAt(i) == '-' && operatorEncountered == false)
  228. finalExpression += '+';
  229. finalExpression += "" + expression.charAt(i);
  230. if((expression.charAt(i) == '+' || expression.charAt(i) == '/' || expression.charAt(i) == '^'
  231. || expression.charAt(i) == '*'))
  232. operatorEncountered = true;
  233. else if(expression.charAt(i) != ' ')
  234. operatorEncountered = false;
  235. }
  236. }
  237.  
  238. String myTempString = "";
  239.  
  240. for(int i = 0; i < finalExpression.length(); i++){
  241. if(finalExpression.charAt(i) != ' '){
  242. myTempString += "" + finalExpression.charAt(i);
  243. }
  244. }
  245.  
  246. finalExpression = myTempString;
  247.  
  248. ArrayList<String> totalNumbers = new ArrayList<String>(0);
  249. ArrayList<Character> totalOperations = new ArrayList<Character>(0);
  250. System.out.println(finalExpression);
  251.  
  252. for(int i = 0; i < finalExpression.length(); i++){
  253. if((int)finalExpression.charAt(i) >= (int)'0' && (int)finalExpression.charAt(i) <= (int)'9'
  254. || finalExpression.charAt(i) == '-'){
  255. String temp = "";
  256. for(int j = i; j < finalExpression.length(); j++){
  257. if(finalExpression.charAt(j) >= '0' && finalExpression.charAt(j) <= '9'
  258. || finalExpression.charAt(j) == '-'){
  259. temp += "" + finalExpression.charAt(j);
  260. }else break;
  261. }
  262. totalNumbers.add(temp);
  263. i += temp.length() == 0 ? 0 : (temp.length() - 1);
  264. }else if(finalExpression.charAt(i) == '*'
  265. || finalExpression.charAt(i) == '/'
  266. || finalExpression.charAt(i) == '^'
  267. || finalExpression.charAt(i) == '+'
  268. ){
  269. totalOperations.add(new Character(finalExpression.charAt(i)));
  270. }
  271. }
  272.  
  273. String result = "";
  274.  
  275. for(int i = 0; i < totalOperations.size(); i++){
  276. if(totalOperations.get(i).equals(new Character('^'))){
  277. result = doOperation(totalNumbers.get(i), (char)totalOperations.get(i), totalNumbers.get(i + 1));
  278. totalOperations.set(i, null);
  279. totalNumbers.set(i, result);
  280. totalNumbers.set(i + 1, null);
  281. totalOperations.remove(i);
  282. totalNumbers.remove(i + 1);
  283. i--;
  284. }
  285. }
  286.  
  287. for(int i = 0; i < totalOperations.size(); i++){
  288. if(totalOperations.get(i).equals(new Character('*'))
  289. || totalOperations.get(i).equals(new Character('/'))){
  290. result = doOperation(totalNumbers.get(i), (char)totalOperations.get(i), totalNumbers.get(i + 1));
  291. totalOperations.set(i, null);
  292. totalNumbers.set(i, result);
  293. totalNumbers.set(i + 1, null);
  294. totalOperations.remove(i);
  295. totalNumbers.remove(i + 1);
  296. i--;
  297.  
  298. }
  299. }
  300.  
  301. for(int i = 0; i < totalOperations.size(); i++){
  302. if(totalOperations.get(i).equals(new Character('+'))){
  303. result = doOperation(totalNumbers.get(i), (char)totalOperations.get(i), totalNumbers.get(i + 1));
  304. totalOperations.set(i, null);
  305. totalNumbers.set(i, result);
  306. totalNumbers.set(i + 1, null);
  307. totalOperations.remove(i);
  308. totalNumbers.remove(i + 1);
  309. i--;
  310. }
  311. }
  312.  
  313. return totalNumbers.get(0);
  314. }
  315. }
  316.  
  317. private static void sleep(int millis){
  318. try{
  319. Thread.sleep(millis);
  320. }catch(Exception e){}
  321. }
  322.  
  323. /**
  324. * Checks to see if the expression is solvable or not.
  325. */
  326. private static boolean isSolvable(String eq){
  327.  
  328. int paranthesisCount = 0;
  329.  
  330. /*
  331. * LOGIC:
  332. * -For all characters in the String eq
  333. * -If a character encountered is equal to a left paranthesis
  334. * -Increment the paranthesis count
  335. * -Else If a character encountered is equal to a right paranthesis
  336. * -Decrement the paranthesis count
  337. * -return true if the count is zero, otherwise return false, and the reasoning
  338. * for this is because if the paranthesis in the String do not match, the expression
  339. * cannot be solved.
  340. */
  341. for(char element : eq.toCharArray()){
  342. if(element == '(')
  343. paranthesisCount++;
  344. else if(element == ')')
  345. paranthesisCount--;
  346. }
  347. return paranthesisCount == 0;
  348. }
  349.  
  350. public static String solve(String eq){
  351. if(isSolvable(eq)){
  352. EquationSolver es = new EquationSolver();
  353. return es.new ExpressionNode(eq).toString();
  354. }else return "";
  355. }
  356.  
  357. }
 
0
Alex Edwards Alex Edwards is offline Offline | Nov 6th, 2008
Ok, here's a fairly good version that evaluates floating-types well and also converts minus-negatives into positive values (90% accuracy).

  1. import java.util.*;
  2. import java.io.*;
  3. import java.text.*;
  4. import java.math.*;
  5. /****************************************
  6.  * @Author: Mark Alexander Edwards Jr.
  7.  *
  8.  * Utility class for solving equations.
  9.  ****************************************/
  10. public final class EquationSolver{ // Utility classes don't need extensions!
  11.  
  12. private EquationSolver(){} // Utility classes don't need to be instantiated!
  13.  
  14. /*Constants*/
  15. private static final Character POW = new Character('^'); // The power character
  16. private static final Character MUL = new Character('*'); // The multiplication character
  17. private static final Character DIV = new Character('/'); // The division character
  18. private static final Character MOD = new Character('%'); // The modulus character
  19. private static final Character ADD = new Character('+'); // The addition character
  20. private static final DecimalFormat DF = new DecimalFormat(); // Our beloved formatter for floating-point values
  21. private static final StringBuffer SB = new StringBuffer(); // A dummy StringBuffer
  22. private static final MathContext MC = new MathContext(40); // Precision-value for BigDecimals
  23.  
  24. /**
  25. * A Means of testing the program.
  26. */
  27. public static void main(String... args){
  28. System.out.println(EquationSolver.solve("5 + 3 * (8 - 4)"));
  29. System.out.println();
  30. System.out.println(EquationSolver.solve("12 / (3 * 4) + 5"));
  31. System.out.println();
  32. BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
  33. while(true){
  34. System.out.print("Enter an equation you would like to solve: ");
  35. try{
  36. String temp = br.readLine();
  37. long t1 = System.nanoTime();
  38. System.out.println( "Answer: " + EquationSolver.solve(temp, 4) );
  39. long t2 = System.nanoTime();
  40. System.out.println( "\nTime taken to calculate value: " + (t2-t1) + " nanoseconds" );
  41. }catch(Exception e){}
  42. }
  43. }
  44.  
  45. /**
  46. * Performs an operation on the two numbers specified
  47. */
  48. private static String doOperation(String lhs, char operator, String rhs){
  49. BigDecimal bdLhs = new BigDecimal(lhs);
  50. BigDecimal bdRhs = new BigDecimal(rhs);
  51. switch(operator){
  52. case '^':
  53. return "" + Math.pow( bdLhs.doubleValue(), bdRhs.doubleValue() );
  54. case '*':
  55. return "" + bdLhs.multiply(bdRhs).toString();
  56. case '/':
  57. return "" + bdLhs.divide(bdRhs, MC).toString();
  58. case '+':
  59. return "" + bdLhs.add(bdRhs).toString();
  60. case '%':
  61. return "" + bdLhs.remainder(bdRhs).toString();
  62. }
  63. return "";
  64. }
  65.  
  66. /**
  67. * Returns a corrected version of the String, which is one that
  68. * has its first and last paranthesis removed.
  69. */
  70. private static String correctedString(String arg){
  71.  
  72. /*
  73. * LOGIC:
  74. * -For every character in arg
  75. * -If a left paranthesis character is found and it is the first one found
  76. * -set foundFirst to true and do not add that character to the StringBuilder
  77. * -Else
  78. * -append to the StringBuilder the current character
  79. *
  80. * -make arg point to a reversed version of the StringBuilder's String
  81. * -clear the StringBuilder for reuse
  82. * -reset foundFirst (since we're planning on trying again)
  83. *
  84. * -For every character in arg
  85. * -If a right paranthesis character is found and it is the first one found
  86. * -set foundFirst to true and do not add that character to the StringBuilder
  87. * -Else
  88. * -append to the StringBuilder the current character
  89. *
  90. * -make arg point to a reversed version of the StringBuilder's String
  91. * -return arg
  92. */
  93. StringBuilder sb = new StringBuilder(); // A Mutable String
  94. boolean foundFirst = false;
  95. for(int i = 0; i < arg.length(); i++)
  96. if(foundFirst == false && arg.charAt(i) == '(')
  97. foundFirst = true;
  98. else sb.append(arg.charAt(i));
  99.  
  100. arg = new StringBuilder(sb.reverse()).toString();
  101. sb.delete(0, sb.length());
  102.  
  103. foundFirst = false;
  104. for(int i = 0; i < arg.length(); i++)
  105. if(foundFirst == false && arg.charAt(i) == ')')
  106. foundFirst = true;
  107. else sb.append(arg.charAt(i));
  108.  
  109. return arg = new StringBuilder(sb.reverse()).toString();
  110. }
  111.  
  112. /**
  113. * Provides a means of halting a process for a specified amount of time
  114. * without directly using the static Thread method sleep.
  115. *
  116. * Used for debugging purposes
  117. */
  118. private static void sleep(int mill){
  119. long t1 = System.currentTimeMillis(); // get the current time
  120. long t2 = t1 + mill; // assign t2 the value of t1 + mill seconds in the future
  121. while((t1 = System.currentTimeMillis()) < t2); // continue looping until t1 catches up with t2
  122. }
  123.  
  124. /**
  125. * Returns the a String that all of the characters the parameter argu
  126. * has, minus the space characters in the String
  127. */
  128. private static String removeSpaces(String argu){
  129. String temp = "";
  130.  
  131. for(int i = 0; i < argu.length(); i++)
  132. if(argu.charAt(i) != ' ')
  133. temp += "" + argu.charAt(i); // only add non-space characters to temp
  134.  
  135. return temp; // return the desired String
  136. }
  137.  
  138. /**
  139. * Contains an expression that exists within parenthesis
  140. * i.e., (5+3), (6 + 2), etc.
  141. *
  142. * If a set of paranethesis exists within the expression, it must be resolved
  143. * by using another expression object to solve the inner expression.
  144. * i.e., (5 + 3 - 2 + (8 * 7) ) would first result in an ExpressionNode consisting of
  145. * a call to another expression to Solve the inner expression
  146. *
  147. * Returns the result of the calculated ExpressionNode.
  148. * If another expression is found within this one,
  149. * a new ExpressionNode will be created and will solve
  150. * the inner expression.
  151. */
  152. private static String parse(String arg){
  153. /*
  154. * LOGIC:
  155. * -Create a finalExpression for a String and initialize it with an empty String
  156. * -For every character in the expression
  157. * -If a left paranthesis is encountered (denoting an inner expression)
  158. * -Create a placeholder for a String and initialize it with a left paranthesis character
  159. * -initialize valuesCounted as an int with the value of 1, denoting that we have at least 1 value
  160. * -For every character, starting at that parenthesis (not including that paranthesis), until valuesCounted is zero
  161. * -If the character is a left paranthesis
  162. * -increment valuesCounted and add the left paranthesis to the placeholder
  163. * -Else If the character is a right paranthesis
  164. * -decrement valuesCounted and add the right paranthesis to the nested placeholder
  165. * -Create an ExpressionNode for the placeHolder String
  166. * -add the toString of the ExpressionNode to the finalExpression String
  167. * -increment i by the length - 1 of the placeHolder
  168. * -Else if the character is a '-' character
  169. * -append a + to the finalExpression String
  170. * -append a - to the finalExpression String
  171. * -Else
  172. * -add the character to the finalExpression String
  173. *
  174. * -Create a resizable array named totalNumbers to store the numbers in the expression
  175. * -Create a resizable array named totalOperations to store the operators in the expression
  176. *
  177. * -Create a temporary String for the compressed version of the finalExpression
  178. * -For every character in the finalExpression
  179. * -If the character is not equal to a space character
  180. * -append the character to the temporary String
  181. * -make finalExpression point to the temporary String
  182. *
  183. * -For every character in finalExpression
  184. * -If the character encountered is between characters '1' and '9' or is a minus sign '-'
  185. * -store the current value of i into storedNumber [???]
  186. * -Create a temp String to collect characters for the number
  187. * -For every number character in the number set selected
  188. * -Concatenate that number to the temp String
  189. * -add the temp String to the ArrayList totalNumbers
  190. * -advance i by (the length of the temp String - 1)
  191. * -Else if the character encountered is '*', '+', '/', '^'
  192. * -store the character in the ArrayList totalOperations
  193. *
  194. * -Create a temp String to hold the final result
  195. *
  196. * -For every Character object in totalOperations, using an int named i as a means to track values
  197. * -If the Character object in totalOperations, located at i, is equal to ^
  198. * -perform the power operation of the Integer form of the String at location i
  199. * of the totalNumbers array with the Integer form of the String at location i + 1
  200. * of the totalNumbers array and store the result in the temp String.
  201. * -set the value of the Character object in totalOperations at i to null
  202. * -set the value of the String object in totalNumbers at i + 1 to null
  203. * -set the value of the String object in totalNumbers at i to be that of the temp String
  204. * -trim the totalOperations array to a new size, so the null value is removed
  205. * -trim the totalNumbers array to a new size, so the null value is removed
  206. * -decrement i
  207. *
  208. * -clear the temp String
  209. * -For every Character object in totalOperations, using an int named i as a means to track values
  210. * -If the Character object in totalOperations, located at i, is equal to *, /, or %
  211. * -perform the necessary operation of the Integer form of the String at location i
  212. * of the totalNumbers array with the Integer form of the String at location i + 1
  213. * of the totalNumbers array and store the result in the temp String.
  214. * -set the value of the Character object in totalOperations at i to null
  215. * -set the value of the String object in totalNumbers at i + 1 to null
  216. * -set the value of the String object in totalNumbers at i to be that of the temp String
  217. * -trim the totalOperations array to a new size, so the null value is removed
  218. * -trim the totalNumbers array to a new size, so the null value is removed
  219. * -decrement i
  220. *
  221. * -clear the temp String
  222. * -For every Character object in totalOperations, using an int named i as a means to track values
  223. * -If the Character object in totalOperations, located at i, is equal to +
  224. * -Create a temp String to hold the final result
  225. * -perform the necessary operation of the Integer form of the String at location i
  226. * of the totalNumbers array with the Integer form of the String at location i + 1
  227. * of the totalNumbers array and store the result in the temp String.
  228. * -set the value of the Character object in totalOperations at i to null
  229. * -set the value of the String object in totalNumbers at i + 1 to null
  230. * -set the value of the String object in totalNumbers at i to be that of the temp String
  231. * -decrement i
  232. *
  233. * -return the first element of totalNumbers
  234. */
  235. String expression = removeSpaces(correctedString(arg)); // Removes paranthesis and spaces from the String expression
  236. String finalExpression = ""; // Placeholder for the final String before values and operands are parsed
  237.  
  238. boolean operatorEncountered = true; // Used to determine if the previous value encountered is an operand
  239. for(int i = 0; i < expression.length(); i++){ // for all of the characters in the String expression
  240. if(expression.charAt(i) == '('){ // if we encounter a left paranthesis, the value must be a nested expression
  241. String placeHolder = "("; // to prevent problems determining during boolean expression-checks
  242. int valuesCounted = 1; // i.e., when should we stop? When valuesCounted is 0?
  243. operatorEncountered = false; // because this will evaluate to be a number, we don't want to consider
  244. // this char-expression to be an operand
  245. for(int j = i + 1; valuesCounted != 0; j++){ // We know that i has to be "(" and we've accounted for it, so i+1 is what we'll use
  246. if(expression.charAt(j) == '(') // if we encounted a left paranthesis, increment count
  247. valuesCounted++;
  248. else if(expression.charAt(j) == ')') // else if its a left paranthesis, decrement count
  249. valuesCounted--;
  250.  
  251. placeHolder += "" + expression.charAt(j); // append the character to the expression
  252. }
  253.  
  254. String evaluatedString = parse(placeHolder); // recursive call - evaluate the nested expression
  255. finalExpression += evaluatedString; // append the evaluatedString to the finalExpression String
  256. i+= (placeHolder.length() - 1); // the nested expression is already solved - force i to jump to non-redundant characters
  257. }else{
  258. if(expression.charAt(i) == '-' && operatorEncountered == false) // if we encountered a minus sign and we didn't encounter any operands
  259. // before it, changes the subtraction to plus a negative
  260. finalExpression += '+';
  261.  
  262. finalExpression += "" + expression.charAt(i); // append the character to the expression
  263. if((expression.charAt(i) == '+'
  264. || expression.charAt(i) == '/'
  265. || expression.charAt(i) == '^'
  266. || expression.charAt(i) == '*'
  267. || expression.charAt(i) == '%'
  268. || expression.charAt(i) == '-')) // if we encounter a valid operand (including minus), flag operandEncountereed to be true
  269. operatorEncountered = true;
  270. else if(expression.charAt(i) != ' ') // else if we dont encounter whitespace nor an operand, flag operand to be false
  271. operatorEncountered = false;
  272. }
  273. }
  274.  
  275. finalExpression = removeSpaces(finalExpression); // for safety measures, removing whitespace again
  276. String perfectExpression = ""; // I'm planning on storing a better version of the finalExpression here
  277.  
  278. for(int i = 0; i < finalExpression.length(); i++){ // for every character in the String finalExpression
  279. if((i + 1) < finalExpression.length()) // to prevent overshooting the array, this measure is taken
  280. if(finalExpression.charAt(i) == '-' && finalExpression.charAt(i + 1) == '-') // if there are two - chars next to each other
  281. i+=2; // ignore them.
  282. perfectExpression += "" + finalExpression.charAt(i); // append to the perfectExpression
  283. }
  284. finalExpression = perfectExpression; // make finalExpression point to the same address as perfectExpression
  285.  
  286. ArrayList<String> totalNumbers = new ArrayList<String>(0); // I'm planning to use this to store Number values (as Strings)
  287. ArrayList<Character> totalOperations = new ArrayList<Character>(0); // I'm planning to use this to store Operand values (as Characters)
  288. System.out.println(finalExpression); // Technically a debug, but it adds a nice touch to the program.
  289.  
  290. //sleep(1000); // for debugging - this can be removed or commented out
  291.  
  292. for(int i = 0; i < finalExpression.length(); i++){ // for every character in the finalExpression
  293. if(finalExpression.charAt(i) >= '0' && finalExpression.charAt(i) <= '9'
  294. || finalExpression.charAt(i) == '-' || finalExpression.charAt(i) == '.'){ // if our character is part of a number
  295. String temp = ""; //
  296. for(int j = i; j < finalExpression.length(); j++){ // We're technically breaking good programming practice here--
  297. // I don't intend on traversing the entire String. We're breaking
  298. // out of this loop the moment a non-numeric character is encountered
  299. if(finalExpression.charAt(j) >= '0' && finalExpression.charAt(j) <= '9'
  300. || finalExpression.charAt(j) == '-' || finalExpression.charAt(j) == '.'){
  301. temp += "" + finalExpression.charAt(j); // append to the temporary String
  302. }else break;
  303. }
  304. totalNumbers.add(temp); // add our collected number to the ArrayList
  305. i += temp.length() == 0 ? 0 : (temp.length() - 1); // we don't want to have redundancy, i.e.
  306. // if number 242 is analyzed, 242, 42 and 2 shouldn't be stored, just 242
  307. // so advance i past numbers already analyzed
  308. }else if(finalExpression.charAt(i) == '*'
  309. || finalExpression.charAt(i) == '/'
  310. || finalExpression.charAt(i) == '^'
  311. || finalExpression.charAt(i) == '+'
  312. || finalExpression.charAt(i) == '%'
  313. ){ // If we run into an operand-character, store it in the operand list
  314. totalOperations.add(new Character(finalExpression.charAt(i)));
  315. }
  316. }
  317.  
  318. String result = "";
  319.  
  320. /*
  321. * DESCRIP:
  322. * Nothing to special happening below, just PEMD%AS
  323. *
  324. * This means that Paranthesis are evaluated first (which is technically done per recursive call),
  325. * then Exponents are evaluated on the 2nd-highest level, then Exponents, Division and Modulus are
  326. * analyzed on the 3rd-highest level, and finally addition is performed on the lowest level.
  327. * Subtraction is unnecessary since adding a negative if essentially the same.
  328. *
  329. * The algorithm used to solve the problems is similar to a INORDER version of the Forth Programming
  330. * Language algorithm. Instead of making a stack-based solution, I simply decided to make a iterative
  331. * ( or cursor ) based solution.
  332. *
  333. * Example:
  334. * totalNumbers = [2, 3, 4, 2, 1]
  335. * totalOperations = [+, *, ^, ^];
  336. *
  337. * -Paranthesis analayzed (this happens recursively)
  338. * -Exponent analyzed
  339. * - 4 ^ 2 = 16
  340. * - 16 is stored in place of 4
  341. * - 2 is removed from totalNumbers
  342. * - ^ is removed from totalOperations
  343. * - 1 takes the place of 2's last location
  344. * - ^ takes the place of ^'s last location
  345. * - 16 ^ 1 = 16
  346. * - 16 is stored in place of 16
  347. * - 1 is removed from totalNumbers
  348. * - ^ is removed from totalOperations
  349. *
  350. * totalNumbers = [2, 3, 16]
  351. * totalOperations = [+. *]
  352. *
  353. * -Multiplication, Division, and Modulus analyzed
  354. * - 3 * 16 = 48
  355. * - 48 is stored in place of 3
  356. * - 16 is removed from totalNumbers
  357. * - * is removed from totalOperations
  358. *
  359. * totalNumbers = [2, 48]
  360. * totalOperations = [+]
  361. *
  362. * -Addition (and conceptualyy Subtraction) analyzed
  363. * - 2 + 48 = 50
  364. * - 50 is stored in place of 2
  365. * - 48 is removed from totalNumbers
  366. * - + is removed from totalOperations
  367. *
  368. * -return the value at indice 0 of totalNumbers, which should be 50
  369. */
  370.  
  371. for(int i = 0; i < totalOperations.size(); i++){
  372. if(totalOperations.get(i).equals(POW)){
  373. result = doOperation(totalNumbers.get(i), (char)totalOperations.get(i), totalNumbers.get(i + 1));
  374. totalNumbers.set(i, result);
  375. totalOperations.remove(i);
  376. totalNumbers.remove(i + 1);
  377. i--;
  378. }
  379. }
  380.  
  381. for(int i = 0; i < totalOperations.size(); i++){
  382. if(totalOperations.get(i).equals(MUL)
  383. || totalOperations.get(i).equals(DIV)
  384. || totalOperations.get(i).equals(MOD)){
  385. result = doOperation(totalNumbers.get(i), (char)totalOperations.get(i), totalNumbers.get(i + 1));
  386. totalNumbers.set(i, result);
  387. totalOperations.remove(i);
  388. totalNumbers.remove(i + 1);
  389. i--;
  390. }
  391. }
  392.  
  393. for(int i = 0; i < totalOperations.size(); i++){
  394. if(totalOperations.get(i).equals(ADD)){
  395. result = doOperation(totalNumbers.get(i), (char)totalOperations.get(i), totalNumbers.get(i + 1));
  396. totalNumbers.set(i, result);
  397. totalOperations.remove(i);
  398. totalNumbers.remove(i + 1);
  399. i--;
  400. }
  401. }
  402.  
  403. return totalNumbers.get(0); // return the value remaining in the first position of the ArrayList
  404. }
  405.  
  406. /**
  407. * Checks to see if the expression is solvable or not.
  408. *
  409. * This method is actually a misnomer, because more restrictions
  410. * should be put in place on what a user can determine as solvable.
  411. */
  412. private static boolean isSolvable(String eq){
  413.  
  414. /*
  415. * LOGIC:
  416. * -For all characters in the String eq
  417. * -If a character encountered is equal to a left paranthesis
  418. * -Increment the paranthesis count
  419. * -Else If a character encountered is equal to a right paranthesis
  420. * -Decrement the paranthesis count
  421. * -return true if the count is zero, otherwise return false, and the reasoning
  422. * for this is because if the paranthesis in the String do not match, the expression
  423. * cannot be solved.
  424. */
  425. int paranthesisCount = 0; // assuming 0 paranthesis to begin with
  426. for(char element : eq.toCharArray()){ // for every char in the String eq
  427. if(element == '(') // if the element is a left paranthesis
  428. paranthesisCount++; // increment the paranthesisCount
  429. else if(element == ')') // else if the element is a right paranthesis
  430. paranthesisCount--; // decrement the paranthesisCount
  431.  
  432. if(paranthesisCount < 0) // if brackets aren't in correct order, return false
  433. return false;
  434. }
  435. return paranthesisCount == 0; // return true if paranthesisCount is zero, otherwise return false
  436. }
  437.  
  438. /**
  439. * Attempts to solve an equation
  440. */
  441. public static String solve(String eq){
  442. if(isSolvable(eq)){
  443. System.out.println(eq); // Prints out the equation before it is parsed
  444. String value = "(" + eq + ")"; // Appending paranthesis to the equation for accuracy
  445. return parse(value); // returning the final value of the expression
  446. }else return "";
  447. }
  448.  
  449. /**
  450. * Attempts to solve an equation, with the precision factor taken into account.
  451. *
  452. * The maximum precision is 40, only because the max precision for a MathContext object is 40
  453. * though this is not required and can be changed in future versions.
  454. */
  455. public static String solve(String eq, int precision){
  456. SB.delete(0, SB.length());
  457. return DF.format( (double)Double.parseDouble(solve(eq)), SB, new FieldPosition(precision) ).toString(); // formatted answer
  458. }
  459. }
 
0
Alex Edwards Alex Edwards is offline Offline | Nov 18th, 2008
Implemented Right-to-left evaluations for powers. Negatives were improved (slightly) by making negatives parse as multiplying -1 by the value.

  1. import java.util.*;
  2. import java.io.*;
  3. import java.text.*;
  4. import java.math.*;
  5. /****************************************
  6.  * @Author: Mark Alexander Edwards Jr.
  7.  *
  8.  * Utility class for solving equations.
  9.  ****************************************/
  10. public final class EquationSolver{ // Utility classes don't need extensions!
  11.  
  12. private EquationSolver(){} // Utility classes don't need to be instantiated!
  13.  
  14. /*Constants*/
  15. private static final Character POW = new Character('^');
  16. private static final Character MUL = new Character('*');
  17. private static final Character DIV = new Character('/');
  18. private static final Character MOD = new Character('%');
  19. private static final Character ADD = new Character('+');
  20. private static final Character[] firstSet = {POW}, secondSet = {MUL, DIV, MOD}, thirdSet = {ADD};
  21. private static final DecimalFormat DF = new DecimalFormat();
  22. private static final StringBuffer SB = new StringBuffer();
  23. private static final MathContext MC = new MathContext(40);
  24. private enum Direction {
  25. L_TO_R,
  26. R_TO_L
  27. };
  28.  
  29. /**
  30. * A Means of testing the program.
  31. */
  32. public static void main(String... args){
  33. System.out.println();
  34. System.out.println(EquationSolver.solve("5 + 3 * (8 - 4)"));
  35. System.out.println();
  36. System.out.println(EquationSolver.solve("12 / (3 * 4) + 5"));
  37. System.out.println();
  38. InputStreamReader isr = new InputStreamReader(System.in);
  39. BufferedReader br = new BufferedReader(isr);
  40. while(true){
  41. System.out.print("Enter an equation you would like to solve \n(or enter EXIT to exit program): ");
  42. try{
  43. String temp = br.readLine();
  44.  
  45. if(temp.equalsIgnoreCase("exit")){
  46. try{
  47. isr.close();
  48. br.close();
  49. }catch(Exception f){
  50.  
  51. }finally{
  52. System.exit(0);
  53. }
  54. }
  55.  
  56. long t1 = System.nanoTime();
  57. System.out.println( "Answer: " + EquationSolver.solve(temp, 4) );
  58. long t2 = System.nanoTime();
  59. System.out.println( "\nTime taken to calculate value: " + (t2-t1) + " nanoseconds" );
  60. }catch(Exception e){}
  61. }
  62. }
  63.  
  64. /**
  65. * Performs an operation on the two numbers specified
  66. */
  67. private static String doOperation(String lhs, char operator, String rhs){
  68. BigDecimal bdLhs = new BigDecimal(lhs);
  69. BigDecimal bdRhs = new BigDecimal(rhs);
  70. switch(operator){
  71. case '^':
  72. return "" + Math.pow( bdLhs.doubleValue(), bdRhs.doubleValue() );
  73. case '*':
  74. return "" + bdLhs.multiply(bdRhs).toString();
  75. case '/':
  76. return "" + bdLhs.divide(bdRhs, MC).toString();
  77. case '+':
  78. return "" + bdLhs.add(bdRhs).toString();
  79. case '%':
  80. return "" + bdLhs.remainder(bdRhs).toString();
  81. }
  82. return "";
  83. }
  84.  
  85. /**
  86. * Returns a corrected version of the String, which is one that
  87. * has its first and last paranthesis removed.
  88. */
  89. private static String correctedString(String arg){
  90.  
  91. StringBuilder sb = new StringBuilder(); // A Mutable String
  92. boolean foundFirst = false;
  93. for(int i = 0; i < arg.length(); i++)
  94. if(foundFirst == false && arg.charAt(i) == '(')
  95. foundFirst = true;
  96. else sb.append(arg.charAt(i));
  97.  
  98. arg = new StringBuilder(sb.reverse()).toString();
  99. sb.delete(0, sb.length());
  100.  
  101. foundFirst = false;
  102. for(int i = 0; i < arg.length(); i++)
  103. if(foundFirst == false && arg.charAt(i) == ')')
  104. foundFirst = true;
  105. else sb.append(arg.charAt(i));
  106.  
  107. return arg = new StringBuilder(sb.reverse()).toString();
  108. }
  109.  
  110. /**
  111. * Provides a means of halting a process for a specified amount of time
  112. * without directly using the static Thread method sleep.
  113. *
  114. * Used for debugging purposes
  115. */
  116. private static void sleep(int mill){
  117. long t1 = System.currentTimeMillis();
  118. long t2 = t1 + mill;
  119. while((t1 = System.currentTimeMillis()) < t2);
  120. }
  121.  
  122. /**
  123. * Returns the a String that all of the characters the parameter argu
  124. * has, minus the space characters in the String
  125. */
  126. private static String removeSpaces(String argu){
  127. String temp = "";
  128.  
  129. for(int i = 0; i < argu.length(); i++)
  130. if(argu.charAt(i) != ' ')
  131. temp += "" + argu.charAt(i);
  132.  
  133. return temp;
  134. }
  135.  
  136. /**
  137. * Contains an expression that exists within parenthesis
  138. * i.e., (5+3), (6 + 2), etc.
  139. *
  140. * If a set of paranethesis exists within the expression, it must be resolved
  141. * by using another expression object to solve the inner expression.
  142. * i.e., (5 + 3 - 2 + (8 * 7) ) would first result in an ExpressionNode consisting of
  143. * a call to another expression to Solve the inner expression
  144. *
  145. * Returns the result of the calculated ExpressionNode.
  146. * If another expression is found within this one,
  147. * a new ExpressionNode will be created and will solve
  148. * the inner expression.
  149. */
  150. private static String parse(String arg){
  151.  
  152. String expression = removeSpaces(correctedString(arg));
  153. String finalExpression = "";
  154. boolean operatorEncountered = true;
  155. boolean initialValue = true;
  156. for(int i = 0; i < expression.length(); i++){
  157. if(expression.charAt(i) == '('){
  158. String multiply = "";
  159. if(operatorEncountered == false && initialValue == false){
  160. multiply += "*";
  161. }
  162.  
  163. String placeHolder = "(";
  164. int valuesCounted = 1;
  165. operatorEncountered = false;
  166. for(int j = i + 1; valuesCounted != 0; j++){
  167. if(expression.charAt(j) == '(')
  168. valuesCounted++;
  169. else if(expression.charAt(j) == ')')
  170. valuesCounted--;
  171. placeHolder += "" + expression.charAt(j);
  172. }
  173.  
  174. String evaluatedString = parse(placeHolder);
  175. finalExpression += multiply + evaluatedString;
  176. i+= (placeHolder.length() - 1);
  177. }else{
  178. if(expression.charAt(i) == '-' && operatorEncountered == false){
  179. finalExpression += ((!initialValue) ? "+": "") + expression.charAt(i);
  180. }else if(expression.charAt(i) == '-' && operatorEncountered == true){
  181. finalExpression += "-1*";
  182. }else finalExpression += expression.charAt(i);
  183.  
  184. if((expression.charAt(i) == '+'
  185. || expression.charAt(i) == '/'
  186. || expression.charAt(i) == '^'
  187. || expression.charAt(i) == '*'
  188. || expression.charAt(i) == '%'
  189. || expression.charAt(i) == '-'))
  190. operatorEncountered = true;
  191. else if(expression.charAt(i) != ' ')
  192. operatorEncountered = false;
  193. }
  194. initialValue = false;
  195. }
  196.  
  197. finalExpression = removeSpaces(finalExpression);
  198. String perfectExpression = "";
  199.  
  200. for(int i = 0; i < finalExpression.length(); i++){
  201. if((i + 1) < finalExpression.length())
  202. if(finalExpression.charAt(i) == '-' && finalExpression.charAt(i + 1) == '-')
  203. i+=2;
  204. perfectExpression += "" + finalExpression.charAt(i);
  205. }
  206. finalExpression = perfectExpression;
  207.  
  208. ArrayList<String> totalNumbers = new ArrayList<String>(0);
  209. ArrayList<Character> totalOperations = new ArrayList<Character>(0);
  210. System.out.println(finalExpression);
  211.  
  212. for(int i = 0; i < finalExpression.length(); i++){
  213. if(finalExpression.charAt(i) >= '0' && finalExpression.charAt(i) <= '9'
  214. || finalExpression.charAt(i) == '-' || finalExpression.charAt(i) == '.'
  215. || finalExpression.charAt(i) == ','){
  216. String temp = "";
  217. for(int j = i; j < finalExpression.length(); j++){
  218. if(finalExpression.charAt(j) >= '0' && finalExpression.charAt(j) <= '9'
  219. || finalExpression.charAt(j) == '-' || finalExpression.charAt(j) == '.'
  220. || finalExpression.charAt(j) == ','){
  221. temp += "" + finalExpression.charAt(j);
  222. }else break;
  223. }
  224. totalNumbers.add(temp);
  225. i += temp.length() == 0 ? 0 : (temp.length() - 1);
  226. }else if(finalExpression.charAt(i) == '*'
  227. || finalExpression.charAt(i) == '/'
  228. || finalExpression.charAt(i) == '^'
  229. || finalExpression.charAt(i) == '+'
  230. || finalExpression.charAt(i) == '%'
  231. ){
  232. totalOperations.add(new Character(finalExpression.charAt(i)));
  233. }
  234. }
  235.  
  236. calculate(totalNumbers, totalOperations, firstSet, Direction.R_TO_L);
  237. calculate(totalNumbers, totalOperations, secondSet, Direction.L_TO_R);
  238. calculate(totalNumbers, totalOperations, thirdSet, Direction.L_TO_R);
  239.  
  240. return totalNumbers.get(0);
  241. }
  242.  
  243. /**
  244. * Returns true if the target character exists in the set of Character operands, returns false otherwise.
  245. */
  246. private static boolean containsCharacter(Character anOperation, Character operands[]){
  247. for(Character item : operands){
  248. if(anOperation.equals(item)){
  249. return true;
  250. }
  251. }
  252. return false;
  253. }
  254.  
  255. /**
  256. * Attempts to solve an equation that is seperated into a set of numbers and operands.
  257. * (More to add)
  258. */
  259. private static void calculate(ArrayList<String> totalNumbers, ArrayList<Character> totalOperations, Character operands[], Direction dir){
  260. String result = "";
  261. if(dir == Direction.L_TO_R){
  262. for(int i = 0; i < totalOperations.size(); i++){
  263. if(containsCharacter(totalOperations.get(i), operands)){
  264. result = doOperation(totalNumbers.get(i), (char)totalOperations.get(i), totalNumbers.get(i + 1));
  265. totalNumbers.set(i, result);
  266. totalOperations.remove(i);
  267. totalNumbers.remove(i + 1);
  268. i--;
  269. }
  270. }
  271. }else if(dir == Direction.R_TO_L){
  272. for(int i = totalOperations.size() - 1; i >= 0; i--){
  273. if(containsCharacter(totalOperations.get(i), operands)){
  274. result = doOperation(totalNumbers.get(i), (char)totalOperations.get(i), totalNumbers.get(i + 1));
  275. totalNumbers.set(i, result);
  276. totalOperations.remove(i);
  277. totalNumbers.remove(i + 1);
  278. }
  279. }
  280. }
  281. }
  282.  
  283. /**
  284. * Checks to see if the expression is solvable or not.
  285. *
  286. * This method is actually a misnomer, because more restrictions
  287. * should be put in place on what a user can determine as solvable.
  288. */
  289. private static boolean isSolvable(String eq){
  290.  
  291. int paranthesisCount = 0; // assuming 0 paranthesis to begin with
  292. for(char element : eq.toCharArray()){ // for every char in the String eq
  293. if(element == '(') // if the element is a left paranthesis
  294. paranthesisCount++; // increment the paranthesisCount
  295. else if(element == ')') // else if the element is a right paranthesis
  296. paranthesisCount--; // decrement the paranthesisCount
  297.  
  298. if(paranthesisCount < 0) // if brackets aren't in correct order, return false
  299. return false;
  300. }
  301. return paranthesisCount == 0; // return true if paranthesisCount is zero, otherwise return false
  302. }
  303.  
  304. /**
  305. * Attempts to solve an equation
  306. */
  307. public static String solve(String eq){
  308. if(isSolvable(eq)){
  309. System.out.println(eq); // Prints out the equation before it is parsed
  310. String value = "(" + eq + ")"; // Appending paranthesis to the equation for accuracy
  311. return parse(value); // returning the final value of the expression
  312. }else return "";
  313. }
  314.  
  315. /**
  316. * Attempts to solve an equation, with the precision factor taken into account.
  317. *
  318. * The maximum precision is 40, only because the max precision for the MathContext object is 40
  319. * though this is not required and can be changed in future versions.
  320. */
  321. public static String solve(String eq, int precision){
  322. SB.delete(0, SB.length());
  323. return DF.format( (double)Double.parseDouble(solve(eq)), SB, new FieldPosition(precision) ).toString(); // formatted answer
  324. }
  325. }
 
0
my2milan my2milan is offline Offline | Jan 4th, 2009
sir, how about just checking if the syntax is correct or not??..the syntax of the given equation will be checked based on the order of the variables(maximum of 2 variables), numbers(maximum of 2 numbers), operators(*, -, /, + and ^(power)) and separators(parenthesis only)..terms can be separated with parenthesis and consists of a variable(s)/number(s) and an operator with this format..variable(s)/number(s) followed by an operator then followed by another variable(s)/number(s)..i want to know how to do this..hear you soon..(^_^)
 
0
einjelle einjelle is offline Offline | Sep 20th, 2009
Gee.. Thanks for posting this. (~__~)
Can I have the permission to modify this for binary operations?
 
0
einjelle einjelle is offline Offline | Sep 20th, 2009
Is this supposed to be the output?

5 + 3 * 8 - 4
25

12 / 3 * 4 + 5
21


Ain't the answers supposed to be 17 for the first equation and 5 for the second one?
 
 

Message:


Thread Tools Search this Thread



Tag cloud for Java
About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC