Java – the calculator does not handle two operator equations
•
Java
I am developing a calculator application and all functions have been turned off The only problem is that when I enter an equation that contains two arithmetic operators, it breaks down For example, if you enter "2 √ 9", it will return to 3. If you enter "√ 92", it will be forced to close and "invalid double √ 9" will be displayed Please help.
ScientificCalculator. java
String prevAnswer = ""; TextView formulascreen; TextView resultscreen; String formuladisplay = ""; String resultdisplay = ""; String result = ""; String operator; DecimalFormat res = new DecimalFormat("#,###,###.######"); @Nullable @Override public View onCreateView(LayoutInflater inflater,@Nullable ViewGroup container,@Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.scientific_calculator,container,false); formulascreen = (TextView) view.findViewById(R.id.formulaTextView); updateformuladisplay(); resultscreen = (TextView) view.findViewById(R.id.resultTextView); updateresultdisplay(); view.findViewById(R.id.btn0).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onClickNumber(v); } }); view.findViewById(R.id.btn1).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onClickNumber(v); } }); view.findViewById(R.id.btn2).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onClickNumber(v); } }); view.findViewById(R.id.btn3).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onClickNumber(v); } }); view.findViewById(R.id.btn4).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onClickNumber(v); } }); view.findViewById(R.id.btn5).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onClickNumber(v); } }); view.findViewById(R.id.btn6).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onClickNumber(v); } }); view.findViewById(R.id.btn7).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onClickNumber(v); } }); view.findViewById(R.id.btn8).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onClickNumber(v); } }); view.findViewById(R.id.btn9).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onClickNumber(v); } }); view.findViewById(R.id.btnSqrt).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onClicksqrt(v); } }); view.findViewById(R.id.btnClear).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onClickClear(v); } }); view.findViewById(R.id.btnDel).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onClickDel(v); } }); view.findViewById(R.id.btnAdd).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onClickOperator(v); } }); view.findViewById(R.id.btnMinus).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onClickOperator(v); } }); view.findViewById(R.id.btnDivide).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onClickOperator(v); } }); view.findViewById(R.id.btnMultiply).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onClickOperator(v); } }); view.findViewById(R.id.btnEquals).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onClickEquals(v); } }); view.findViewById(R.id.btnPrevAns).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onClickAns(v); } }); return view; } public void onClickEquals(View view) { getResult(); updateresultdisplay(); } private boolean getResult() { if (operator.equals("")) return false; String[] operation = formuladisplay.split(Pattern.quote(operator)); if (operation.length < 2) return false; if (operator.equals("√")) { result = String.valueOf(res.format(sqrtOp(operator,operation[1]))); resultdisplay = result; prevAnswer = result; result = ""; } else { result = String.valueOf(res.format(simpleOp(operation[0],operation[1],operator))); resultdisplay = result; prevAnswer = result; result = ""; } return true; } public double simpleOp(String a,String b,String op) { switch (op) { case "+": return Double.valueOf(a) + Double.valueOf(b); case "-": return Double.valueOf(a) - Double.valueOf(b); case "x": return Double.valueOf(a) * Double.valueOf(b); case "÷": return Double.valueOf(a) / Double.valueOf(b); default: return -1; } } private void updateformuladisplay() { formulascreen.setText(formuladisplay); } private void updateresultdisplay() { resultscreen.setText(resultdisplay); } public void onClicksqrt(View view) { Button b = (Button) view; operator = b.getText().toString(); formuladisplay += operator; updateformuladisplay(); } public void onClickDel(View view) { if (formuladisplay.length() >= 1) { formuladisplay = formuladisplay.substring(0,formuladisplay.length() - 1); updateformuladisplay(); } } private void clear() { formuladisplay = ""; resultdisplay = ""; } public void onClickClear(View view) { clear(); updateformuladisplay(); updateresultdisplay(); } public void onClickNumber(View view) { //if (!(result.equals(""))) { // clear(); //updateformuladisplay(); //} Button b = (Button) view; if (formuladisplay.length() >= 0 && formuladisplay.length() <= 17) { formuladisplay += b.getText(); updateformuladisplay(); } else { updateformuladisplay(); } } public void onClickOperator(View view) { Button b = (Button) view; operator = b.getText().toString(); formuladisplay += operator; updateformuladisplay(); } public double sqrtOp(String op,String a) { switch (op) { case "√": return Math.sqrt(Double.valueOf(a)); default: return -1; } } public void onClickAns(View view) { Button b = (Button) view; if (formuladisplay.length() >= 0 && formuladisplay.length() <= 10) { formuladisplay += prevAnswer; updateformuladisplay(); } else { updateformuladisplay(); } }
}
Solution
Use stack data structures to evaluate expressions Try this simple class
And add the sqrt operation in the evaluatepostfix method
public class InfixPostfixEvaluator { /** * Operators in reverse order of precedence. */ private static final String operators = "-+/*"; private static final String operands = "0123456789"; public int evalInfix(String infix) { return evaluatePostfix(convert2Postfix(infix)); } public String convert2Postfix(String infixExpr) { char[] chars = infixExpr.tocharArray(); Stack<Character> stack = new Stack<Character>(); StringBuilder out = new StringBuilder(infixExpr.length()); for (char c : chars) { if (isOperator(c)) { while (!stack.isEmpty() && stack.peek() != '(') { if (operatorGreaterOrEqual(stack.peek(),c)) { out.append(stack.pop()); } else { break; } } stack.push(c); } else if (c == '(') { stack.push(c); } else if (c == ')') { while (!stack.isEmpty() && stack.peek() != '(') { out.append(stack.pop()); } if (!stack.isEmpty()) { stack.pop(); } } else if (isOperand(c)) { out.append(c); } } while (!stack.empty()) { out.append(stack.pop()); } return out.toString(); } public int evaluatePostfix(String postfixExpr) { char[] chars = postfixExpr.tocharArray(); Stack<Integer> stack = new Stack<Integer>(); for (char c : chars) { if (isOperand(c)) { stack.push(c - '0'); // convert char to int val } else if (isOperator(c)) { int op1 = stack.pop(); int op2 = stack.pop(); int result; switch (c) { case '*': result = op1 * op2; stack.push(result); break; case '/': result = op2 / op1; stack.push(result); break; case '+': result = op1 + op2; stack.push(result); break; case '-': result = op2 - op1; stack.push(result); break; } } } return stack.pop(); } private int getPrecedence(char operator) { int ret = 0; if (operator == '-' || operator == '+') { ret = 1; } else if (operator == '*' || operator == '/') { ret = 2; } return ret; } private boolean operatorGreaterOrEqual(char op1,char op2) { return getPrecedence(op1) >= getPrecedence(op2); } private boolean isOperator(char val) { return operators.indexOf(val) >= 0; } private boolean isOperand(char val) { return operands.indexOf(val) >= 0; } }
For details, please read http://willcode4beer.com/design.jsp?set=evalInfix
http://www.java2novice.com/data-structures-in-java/stacks/infix-expression/
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
二维码