android 使用递归的计算器应用

android Calculator app using recursion

这是我的计算器应用程序的 MainActivity java 文件:

public class MainActivity extends ActionBarActivity {
private String numString = "";
EditText editTextView;
Button button;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    editTextView = (EditText)findViewById(R.id.textView);
}

//when number buttons are clicked.
public void onButtonClick(View v) {
    button = (Button) v;
    numString += button.getText().toString();
    editTextView.setText(numString);
}

//operation buttons which will also add a space before and after the operator.
public void onButtonSpaceGenerator(View view)
{
    button = (Button)view;
    numString += " ";
    numString += button.getText().toString();
    numString += " ";
    editTextView.setText(numString);
}

public void onClear(View v){
    numString = "";
    editTextView.setText("");
}

public ArrayList<String> createArray(ArrayList<String> arrayList){
    String tempString = "";
    int tempInt = 0;
    int tempIndex = 0;
    int[] array = {};
    for(int i = 0; i < numString.length(); i++) {
        if (numString.substring(i, i + 1) == " ") {
            array[tempInt] = i;
            tempInt++;
        }
    }
    for(int i: array){
        tempString = numString.substring(tempIndex, i);
        Log.d("arrayList!!!!", tempString);
        arrayList.add(tempString);
        tempIndex = i;
    }
    return arrayList;
}

public void equals(View v){
    ArrayList<String> arrayList = new ArrayList<>();
    ArrayList<String> arrayList1 = createArray(arrayList);
    double total = calcResult(arrayList1);
    editTextView.setText(Double.toString(total));
    numString = "";
    arrayList.clear();
    total = 0;
}


public double calcResult(ArrayList<String> aL){
    double tempNum = Double.parseDouble(aL.get(0));
    aL.remove(0);
    if(aL.size() >= 1) {
        String operator = aL.get(0);
        aL.remove(0);
        if (operator.equals("+"))
            return tempNum + calcResult(aL);
        if (operator.equals("*"))
            return tempNum * calcResult(aL);
        if (operator.equals("-"))
            return tempNum - calcResult(aL);
        if (operator.equals("/"))
            return tempNum / calcResult(aL);
    }
    return tempNum;
}

}


而且我不确定为什么,我已经尝试多次调试和检查代码,但我仍然不确定为什么我的数组列表不断提高 indexoutOfBounds 并且非常感谢有关的任何建议我遗漏或做错了什么:

    java.lang.IllegalStateException: Could not execute method of the activity
        at android.view.View.onClick(View.java:3679)
        at android.view.View.performClick(View.java:4203)
        at android.view.View$PerformClick.run(View.java:17189)
        at android.os.Handler.handleCallback(Handler.java:615)
        at android.os.Handler.dispatchMessage(Handler.java:92)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:4950)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1004)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:771)
        at dalvik.system.NativeStart.main(Native Method)
 Caused by: java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at android.view.View.onClick(View.java:3674)
        at android.view.View.performClick(View.java:4203)
        at android.view.View$PerformClick.run(View.java:17189)
        at android.os.Handler.handleCallback(Handler.java:615)
        at android.os.Handler.dispatchMessage(Handler.java:92)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:4950)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1004)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:771)
        at dalvik.system.NativeStart.main(Native Method)
 Caused by: java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
        at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:251)
        at java.util.ArrayList.get(ArrayList.java:304)
        at com.example.android.calculatorrecursion.MainActivity.calcResult(MainActivity.java:79)
        at com.example.android.calculatorrecursion.MainActivity.equals(MainActivity.java:70)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at android.view.View.onClick(View.java:3674)
        at android.view.View.performClick(View.java:4203)
        at android.view.View$PerformClick.run(View.java:17189)
        at android.os.Handler.handleCallback(Handler.java:615)
        at android.os.Handler.dispatchMessage(Handler.java:92)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:4950)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1004)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:771)
        at dalvik.system.NativeStart.main(Native Method)

您的递归中没有中断条件。您尝试始终获取列表的第一个元素,然后检查列表是否为空。您的递归将永远 运行 或抛出异常,因为您的列表是空的。

这是我能想到的一种解决方案:

public double calcResult(ArrayList<String> aL) {
    if (aL.isEmpty()) { //Break condition
        return -1; //Or whatever you like to show an error
    } else {
        double tempNum = Double.parseDouble(aL.get(0));
        aL.remove(0);

        if (!aL.isEmpty()) { //Break condition
            String operator = aL.get(0);
            aL.remove(0);

            if (operator.equals("+"))
                return tempNum + calcResult(aL);
            if (operator.equals("*"))
                return tempNum * calcResult(aL);
            if (operator.equals("-"))
                return tempNum - calcResult(aL);
            if (operator.equals("/"))
                return tempNum / calcResult(aL);

            return tempNum;
        }else{
            return tempNum;
        }
    }
}

我建议您使用 Queue 而不是 ArrayList,因为您只会获取 List 的第一个元素并在其末尾添加新元素 - 这正是 Queue 所做的。