上學期上課寫的計算機,寫好用Stack的寫法之後,想說再試試看用樹狀結構跑中序,有bug,又想說哪一天有空再來改,結果一拖就是一學期...
layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText android:layout_height="wrap_content" android:id="@+id/editText_result"
android:layout_width="match_parent" android:hint="1+2-3" android:focusable="false">
</EditText>
<TableLayout android:layout_width="match_parent"
android:layout_height="wrap_content" android:stretchColumns="*">
<TableRow>
<Button android:text="1" android:id="@+id/button_num1"
android:layout_width="match_parent" android:layout_height="wrap_content" />
<Button android:text="2" android:id="@+id/button_num2"
android:layout_width="match_parent" android:layout_height="wrap_content" />
<Button android:text="3" android:id="@+id/button_num3"
android:layout_height="wrap_content" android:layout_width="match_parent" />
</TableRow>
<TableRow>
<Button android:text="4" android:id="@+id/button_num4"
android:layout_width="match_parent" android:layout_height="wrap_content" />
<Button android:text="5" android:id="@+id/button_num5"
android:layout_width="match_parent" android:layout_height="wrap_content" />
<Button android:text="6" android:id="@+id/button_num6"
android:layout_height="wrap_content" android:layout_width="match_parent" />
</TableRow>
<TableRow>
<Button android:text="7" android:id="@+id/button_num7"
android:layout_width="match_parent" android:layout_height="wrap_content" />
<Button android:text="8" android:id="@+id/button_num8"
android:layout_width="match_parent" android:layout_height="wrap_content" />
<Button android:text="9" android:id="@+id/button_num9"
android:layout_height="wrap_content" android:layout_width="match_parent" />
</TableRow>
<TableRow>
<Button android:text="+" android:id="@+id/button_plus"
android:layout_width="match_parent" android:layout_height="wrap_content" />
<Button android:text="-" android:id="@+id/button_sub"
android:layout_width="match_parent" android:layout_height="wrap_content" />
<Button android:text="=" android:id="@+id/button_amount"
android:layout_height="wrap_content" android:layout_width="match_parent" />
</TableRow>
</TableLayout>
</LinearLayout>
第一種 使用Stack
原理就是把符號跟數字分別拆到個別的Stack,然後再put出來,依據符號進行計算。
package npust.edu.klab;
import java.util.Stack;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
public class Calculator extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// set all ui component.
final EditText edtxt_result = (EditText) this
.findViewById(R.id.editText_result);
Button btn_amount = (Button) this.findViewById(R.id.button_amount);
//to hide the virtual keyboard.
InputMethodManager imm = (InputMethodManager)getSystemService(INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(edtxt_result.getWindowToken(), 0);
// get all button then set a listener for general.
Button[] btns = { (Button) this.findViewById(R.id.button_num1),
(Button) this.findViewById(R.id.button_num2),
(Button) this.findViewById(R.id.button_num3),
(Button) this.findViewById(R.id.button_num4),
(Button) this.findViewById(R.id.button_num5),
(Button) this.findViewById(R.id.button_num6),
(Button) this.findViewById(R.id.button_num7),
(Button) this.findViewById(R.id.button_num8),
(Button) this.findViewById(R.id.button_num9),
(Button) this.findViewById(R.id.button_plus),
(Button) this.findViewById(R.id.button_sub) };
OnClickListener generalOnClick = new OnClickListener() {
public void onClick(View v) {
// set the txt of editText plus the text of button.
edtxt_result.setText(edtxt_result.getText().toString()
+ ((Button) v).getText());
}
};
for (Button btn : btns)
btn.setOnClickListener(generalOnClick);
// calculate
btn_amount.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
String formula = edtxt_result.getText().toString();
// stacks for '+'、'-' and numbers.
Stack symbols = new Stack();
Stack nums = new Stack();
// split by '+'、'-'
String[] numAry = formula.toString().split("[\\+\\-/]");
// set stacks.
for (String num : numAry)
nums.push(Integer.valueOf(num));
for (char c : formula.toCharArray())
if (c == '+' || c == '-')
symbols.push(c);
// calculate by symbol.
int result = 0;
while (!symbols.isEmpty()) {
switch (symbols.pop()) {
case '+':
result += nums.pop();
break;
case '-':
result -= nums.pop();
break;
}
}
// plus the last num in stack.
result += nums.pop();
if(result<0){
edtxt_result.setText("");
edtxt_result.setHint("不支援負數計算");
}
else
edtxt_result.setText(result + "");
}
});
}
}
第二種 使用樹狀結構
就是依據樹狀中序去做運算,結構如圖。
package npust.edu.klab;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
public class Calculator extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// set all ui component.
final EditText edtxt_result = (EditText) this
.findViewById(R.id.editText_result);
Button btn_amount = (Button) this.findViewById(R.id.button_amount);
// to hide the virtual keyboard.
InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(edtxt_result.getWindowToken(), 0);
// get all button then set a listener for general.
Button[] btns = { (Button) this.findViewById(R.id.button_num1),
(Button) this.findViewById(R.id.button_num2),
(Button) this.findViewById(R.id.button_num3),
(Button) this.findViewById(R.id.button_num4),
(Button) this.findViewById(R.id.button_num5),
(Button) this.findViewById(R.id.button_num6),
(Button) this.findViewById(R.id.button_num7),
(Button) this.findViewById(R.id.button_num8),
(Button) this.findViewById(R.id.button_num9),
(Button) this.findViewById(R.id.button_plus),
(Button) this.findViewById(R.id.button_sub) };
OnClickListener generalOnClick = new OnClickListener() {
public void onClick(View v) {
// set the txt of editText plus the text of button.
edtxt_result.setText(edtxt_result.getText().toString()
+ ((Button) v).getText());
}
};
for (Button btn : btns)
btn.setOnClickListener(generalOnClick);
// calculate
btn_amount.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// reverse string to create a tree which grow to right side
String formula = new StringBuffer(edtxt_result.getText().toString()).reverse().toString();
Node root = new Node(), now = root;
int last_index_ofSymbol = 0;
for (int i = 0; i < formula.toCharArray().length; i++) {
if (formula.toCharArray()[i] == '+' || formula.toCharArray()[i] == '-') {
now.value = formula.toCharArray()[i] + "";
now.right = new Node();
if(last_index_ofSymbol==0)
now.right.value = formula.substring(last_index_ofSymbol, i);
else
now.right.value = formula.substring(last_index_ofSymbol+1, i);
last_index_ofSymbol = i;
now.left = new Node();
now = now.left;
} else if (i == formula.toCharArray().length - 1) {
now.value = formula.substring(last_index_ofSymbol+1);
}
}
// calculate by symbol.
int result = 0;
result = Node.inOrder(root);
// plus the last num in stack.
if (result < 0) {
edtxt_result.setText("");
edtxt_result.setHint("不支援負數計算");
} else
edtxt_result.setText(result + "");
}
});
}
}
class Node {
public Node() {
value = "";
left = null;
right = null;
}
String value;
Node left;
Node right;
public static int inOrder(Node n){
if(n!=null){
if(n.value.equals("+"))
return inOrder(n.left) + inOrder(n.right);
else if(n.value.equals("-"))
return inOrder(n.left) - inOrder(n.right);
}
return Integer.parseInt(n.value);
}
}
本來以為樹狀結構的話程式碼可以少寫很多,結果根本也沒有,而且一開始向右生長的樹被我寫成向左生長,所以減法一直算錯,自己還在那裏想半天。

兄弟,我在研究您的Stack並且執行看看,
回覆刪除但編譯器說明:
int result = 0;
while (!symbols.isEmpty()) {
switch (symbols.pop()) {
case '+':
result += nums.pop();
break;
case '-':
result -= nums.pop();
break;
}
}
此段程式碼有些錯誤,似乎是與INT、操作碼的錯誤!
是不是型態類型有問題呢?