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 所做的。
这是我的计算器应用程序的 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 所做的。