2016-02-22 2 views
0
package com.javahelps.calculator; 

import android.os.Bundle; 
import android.support.v7.app.ActionBarActivity; 
import android.view.View; 
import android.widget.Button; 
import android.widget.TextView; 

import net.objecthunter.exp4j.Expression; 
import net.objecthunter.exp4j.ExpressionBuilder; 


public class MainActivity extends ActionBarActivity { 
    // IDs of all the numeric buttons 
    private int[] numericButtons = {R.id.btnZero, R.id.btnOne, R.id.btnTwo, R.id.btnThree, R.id.btnFour, R.id.btnFive, R.id.btnSix, R.id.btnSeven, R.id.btnEight, R.id.btnNine}; 
    // IDs of all the operator buttons 
    private int[] operatorButtons = {R.id.btnAdd, R.id.btnSubtract, R.id.btnMultiply, R.id.btnDivide}; 
    // TextView used to display the output 
    private TextView txtScreen; 
    // Represent whether the lastly pressed key is numeric or not 
    private boolean lastNumeric; 
    // Represent that current state is in error or not 
    private boolean stateError; 
    // If true, do not allow to add another DOT 
    private boolean lastDot; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     // Find the TextView 
     this.txtScreen = (TextView) findViewById(R.id.txtScreen); 
     // Find and set OnClickListener to numeric buttons 
     setNumericOnClickListener(); 
     // Find and set OnClickListener to operator buttons, equal button and decimal point button 
     setOperatorOnClickListener(); 
    } 

    /** 
    * Find and set OnClickListener to numeric buttons. 
    */ 
    private void setNumericOnClickListener() { 
     // Create a common OnClickListener 
     View.OnClickListener listener = new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       // Just append/set the text of clicked button 
       Button button = (Button) v; 
       if (stateError) { 
        // If current state is Error, replace the error message 
        txtScreen.setText(button.getText()); 
        stateError = false; 
       } else { 
        // If not, already there is a valid expression so append to it 
        txtScreen.append(button.getText()); 
       } 
       // Set the flag 
       lastNumeric = true; 
      } 
     }; 
     // Assign the listener to all the numeric buttons 
     for (int id : numericButtons) { 
      findViewById(id).setOnClickListener(listener); 
     } 
    } 

    /** 
    * Find and set OnClickListener to operator buttons, equal button and decimal point button. 
    */ 
    private void setOperatorOnClickListener() { 
     // Create a common OnClickListener for operators 
     View.OnClickListener listener = new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       // If the current state is Error do not append the operator 
       // If the last input is number only, append the operator 
       if (lastNumeric && !stateError) { 
        Button button = (Button) v; 
        txtScreen.append(button.getText()); 
        lastNumeric = false; 
        lastDot = false; // Reset the DOT flag 
       } 
      } 
     }; 
     // Assign the listener to all the operator buttons 
     for (int id : operatorButtons) { 
      findViewById(id).setOnClickListener(listener); 
     } 
     // Decimal point 
     findViewById(R.id.btnDot).setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       if (lastNumeric && !stateError && !lastDot) { 
        txtScreen.append("."); 
        lastNumeric = false; 
        lastDot = true; 
       } 
      } 
     }); 
     // Clear button 
     findViewById(R.id.btnClear).setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       txtScreen.setText(""); // Clear the screen 
       // Reset all the states and flags 
       lastNumeric = false; 
       stateError = false; 
       lastDot = false; 
      } 
     }); 
     // Equal button 
     findViewById(R.id.btnEqual).setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       onEqual(); 
      } 
     }); 
    } 

    /** 
    * Logic to calculate the solution. 
    */ 
    private void onEqual() { 
     // If the current state is error, nothing to do. 
     // If the last input is a number only, solution can be found. 
     if (lastNumeric && !stateError) { 
      // Read the expression 
      String txt = txtScreen.getText().toString(); 
      // Create an Expression (A class from exp4j library) 
      Expression expression = new ExpressionBuilder(txt).build(); 
      try { 
       // Calculate the result and display 
       double result = expression.evaluate(); 
       txtScreen.setText(Double.toString(result)); 
       lastDot = true; // Result contains a dot 
      } catch (ArithmeticException ex) { 
       // Display an error message 
       txtScreen.setText("Error"); 
       stateError = true; 
       lastNumeric = false; 
      } 
     } 
    } 
} 

Я использую этот код для вычисления строки, но этот код вычисляет строку без учета порядка приоритета. Exp 3 + 3 * 3 выход 12,0 Но я хотел бы получить на выходе 18,0 Расчет должен идти слева направо, как я могу изменить этот кодAndroid Calcluate String слева направо

+1

Поскольку ваша логика вычислений находится внутри вашего вызова библиотечного метода 'evaluation()', мы не можем помочь вам, если мы не увидим этот код. Очевидно, есть способы делать математические вычисления со строковыми входами, но тогда вам придется откатить свой собственный класс вместо использования библиотеки. – NoChinDeluxe

ответ

0

Я действительно не знаю, почему кто-то whould это нужно, но Ну вот.

У меня есть метод для вас, который вычисляет арифметическую строку слева направо, используя регулярное выражение, которое разбивает элементы на номера double и четыре основных оператора +,-,*./. Затем он вычисляет результат, перемещая все части, сохраняя фактический оператор, и используя его с результатом и фактическим числом.

private double evalLeftToRight(String text){ 
    double result = 0.0f; 
    char actualOperant = ' '; 
    Pattern pattern = Pattern.compile("((\\d*\\.\\d+)|(\\d+)|([\\+\\-\\*/]))"); 
    Matcher m = pattern.matcher(text); 
    while(m.find()) { 
     String part = m.group(); 
     if  (part.equals("+")) actualOperant = '+'; 
     else if(part.equals("-")) actualOperant = '-'; 
     else if(part.equals("*")) actualOperant = '*'; 
     else if(part.equals("/")) actualOperant = '/'; 
     else{ 
      double actualNumber = Double.parseDouble(part); 
      switch(actualOperant){ 
       case ' ': result = actualNumber; break; 
       case '+': result += actualNumber; break; 
       case '-': result -= actualNumber; break; 
       case '*': result *= actualNumber; break; 
       case '/': result /= actualNumber; break; 
      } 
     } 
    } 
    return result; 
} 

Я думаю, вы можете использовать его в своем методе onEqual().

private void onEqual() { 
    [...] 
    String txt = txtScreen.getText().toString(); 
    double result = evalLeftToRight(txt); 
    txtScreen.setText(Double.toString(result)); 
    [...] 
} 
Смежные вопросы