Hello!
I really need your help. I'm new to programming, so I’m sorry if I ask a stupid question :)
I make a calculator for android. It should be able to calculate the expression, for example: (84-12) + (18 + 5)%
Third-party libraries (such as arity) are prohibited.
I have a problem with writing code to calculate interest. It should be just the percentage, not the remainder of the division.
Please suggest links where I can see a similar algorithm (a parser from a string into a mathematics expression with the possibility of calculating interest) or a sample code.
Thank you in advance

equal.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { String orgString = textView.getText().toString(); result.setText(findValue (orgString)); textView.setText(null); clearResult = false; doubleMathActionBug = false; doubleDotBug = true; } public String findValue (String finalStr) { while (finalStr.contains("(") && finalStr.contains(")")) { int fIndex = finalStr.indexOf("("); int nIndex = finalStr.indexOf(")"); String subString = finalStr.substring(fIndex + 1, nIndex); finalStr = finalStr.substring(0, fIndex) + calculate(subString) + finalStr.substring(nIndex + 1, finalStr.length()); } return calculate(finalStr); } public String calculate(String finalString) { while (finalString.contains("(") && finalString.contains(")")) { findValueInBraces(finalString); } while (!isNum(finalString)) { List<Integer> positions = getOperandPosition(finalString); int pos = positions.get(0); if (positions.size() >= 2 && positions.get(1) != null) { int nxtPos = positions.get(1); finalString = getValue(finalString.substring(0, nxtPos), pos) + finalString.substring(nxtPos, finalString.length()); } else { finalString = getValue( finalString.substring(0, finalString.length()), pos); } } return finalString; } public boolean isNum(String str) { if (str.contains("+") || str.contains("-") || str.contains("*") || str.contains("/") || str.contains("%")) { return false; } return true; } public List<Integer> getOperandPosition(String str) { List<Integer> integers = new ArrayList<Integer>(); if (str.contains("+")) { integers.add(str.indexOf("+")); } if (str.contains("-")) { integers.add(str.indexOf("-")); } if (str.contains("*")) { integers.add(str.indexOf("*")); } if (str.contains("/")) { integers.add(str.indexOf("/")); } if (str.contains("%")) { integers.add(str.indexOf("%")); } Collections.sort(integers); return integers; } public String getValue(String str, int pos) { double finalVal = 0; double a = Double.parseDouble(str.substring(0, pos)); double b = Double.parseDouble(str.substring(pos + 1, str.length())); char c = str.charAt(pos); if (c == '*') { finalVal = a * b; } else if (c == '/') { finalVal = a / b; } else if (c == '+') { finalVal = a + b; } else if (c == '-') { finalVal = a - b; }else if (c == '%') { c = str.charAt(0, pos); if (c == '*') { finalVal = a/100*b; } else if (c == '+') { finalVal = a + a/100*b; } else if (c == '-') { finalVal = a - a/100*b; } } return String.valueOf(finalVal); } }); 
  • one
    What exactly is the problem when calculating interest. Please publish your code, even if it does not work. - 0xdb
  • Thanks for the response, added the code to the question. I think the problem is at the very end (where%). I don’t quite understand how to write logic for ==% - Elena
  • c = str.charAt(0, pos); inside if (c == '%') It seems to be c = str.charAt(pos-1); or something like that. You need the previous statement there, not the same one. - lllyct
  • In general, I would advise you to dig in the direction of the reverse Polish record, it allows you to deal with the problems of the sequence of operations, brackets and all that. - lllyct
  • A built-in java whether to use? For example ScriptManager docs.oracle.com/javase/7/docs/technotes/guides/scripting/… - Chubatiy

1 answer 1

Found the answer (thanks to the comments). Here is the code for the calculator with the possibility of calculating interest (input line, for example (158 + 15) * 18%)

 public class ReversePolishNotation { public static final Map<String, Integer> MAIN_MATH_OPERATIONS; static { MAIN_MATH_OPERATIONS = new HashMap<String, Integer>(); MAIN_MATH_OPERATIONS.put("%", 1); MAIN_MATH_OPERATIONS.put("*", 2); MAIN_MATH_OPERATIONS.put("/", 2); MAIN_MATH_OPERATIONS.put("+", 3); MAIN_MATH_OPERATIONS.put("-", 3); } public static String sortingStation(String expression, Map<String, Integer> operations, String leftBracket, String rightBracket) { if (expression == null || expression.length() == 0) throw new IllegalStateException("Expression isn't specified."); if (operations == null || operations.isEmpty()) throw new IllegalStateException("Operations aren't specified."); List<String> out = new ArrayList<String>(); Stack<String> stack = new Stack<String>(); expression = expression.replace(" ", ""); Set<String> operationSymbols = new HashSet<String>(operations.keySet()); operationSymbols.add(leftBracket); operationSymbols.add(rightBracket); int index = 0; boolean findNext = true; while (findNext) { int nextOperationIndex = expression.length(); String nextOperation = ""; for (String operation : operationSymbols) { int i = expression.indexOf(operation, index); if (i >= 0 && i < nextOperationIndex) { nextOperation = operation; nextOperationIndex = i; } } if (nextOperationIndex == expression.length()) { findNext = false; } else { if (index != nextOperationIndex) { out.add(expression.substring(index, nextOperationIndex)); } if (nextOperation.equals(leftBracket)) { stack.push(nextOperation); } else if (nextOperation.equals(rightBracket)) { while (!stack.peek().equals(leftBracket)) { out.add(stack.pop()); if (stack.empty()) { throw new IllegalArgumentException("Unmatched brackets"); } } stack.pop(); } else { while (!stack.empty() && !stack.peek().equals(leftBracket) && (operations.get(nextOperation) >= operations.get(stack.peek()))) { out.add(stack.pop()); } stack.push(nextOperation); } index = nextOperationIndex + nextOperation.length(); } } if (index != expression.length()) { out.add(expression.substring(index)); } while (!stack.empty()) { out.add(stack.pop()); } StringBuffer result = new StringBuffer(); if (!out.isEmpty()) result.append(out.remove(0)); while (!out.isEmpty()) result.append(" ").append(out.remove(0)); return result.toString(); } public static String sortingStation(String expression, Map<String, Integer> operations) { return sortingStation(expression, operations, "(", ")"); } public static BigDecimal calculateExpression(String expression) { String rpn = sortingStation(expression, MAIN_MATH_OPERATIONS); StringTokenizer tokenizer = new StringTokenizer(rpn, " "); Stack<BigDecimal> stack = new Stack<BigDecimal>(); while (tokenizer.hasMoreTokens()) { String token = tokenizer.nextToken(); if (!MAIN_MATH_OPERATIONS.keySet().contains(token)) { stack.push(new BigDecimal(token)); } else { BigDecimal operand2 = stack.pop(); BigDecimal operand1 = stack.empty() ? BigDecimal.ZERO : stack.pop(); if (token.equals("*")) { stack.push(operand1.multiply(operand2)); } else if (token.equals("/")) { stack.push(operand1.divide(operand2)); } else if (token.equals("+")) { stack.push(operand1.add(operand2)); } else if (token.equals("-")) { stack.push(operand1.subtract(operand2)); }else if (token.equals("%")) { token = tokenizer.nextToken(); if (token.equals("*")) { stack.push(operand1.multiply(operand2.divide(BigDecimal.valueOf(100)))); } else if (token.equals("/")) { stack.push(operand1.divide(operand1.multiply(operand2.divide(BigDecimal.valueOf(100))))); } else if (token.equals("+")) { stack.push(operand1.multiply(operand2.divide(BigDecimal.valueOf(100)).add(BigDecimal.valueOf(1)))); } else if (token.equals("-")) { stack.push(operand1.subtract(operand1.multiply(operand2.divide(BigDecimal.valueOf(100))))); } } } } if (stack.size() != 1) throw new IllegalArgumentException("Expression syntax error."); return stack.pop(); } private ReversePolishNotation() { } 

}