Android簡易計算機(四)-完全な論理コード
19792 ワード
最近、アンドロイドに関する知識を学んでいます.最初のdemoは簡易計算機を作りました.携帯電話に付属している計算機を真似ています.括弧をつけず、簡単な4つの演算で、長表現式の演算をサポートしています.このページには、今回の簡易計算機の完全な論理コードが貼られています.
コードは次のとおりです.
コードは次のとおりです.
package com.example.zwkkkk1.caculator1;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import java.math.BigDecimal;
import java.util.Stack;
import java.util.regex.Pattern;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private static String TAG = "CACULATOR";
TextView txt_result, txt_edit;
boolean isOperateDown = false;// , false
boolean isDotDown = false;//. , false
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txt_edit = (TextView)findViewById(R.id.txt_edit);
txt_result = (TextView)findViewById(R.id.txt_result);
findViewById(R.id.btn_0).setOnClickListener(this);
findViewById(R.id.btn_1).setOnClickListener(this);
findViewById(R.id.btn_2).setOnClickListener(this);
findViewById(R.id.btn_3).setOnClickListener(this);
findViewById(R.id.btn_4).setOnClickListener(this);
findViewById(R.id.btn_5).setOnClickListener(this);
findViewById(R.id.btn_6).setOnClickListener(this);
findViewById(R.id.btn_7).setOnClickListener(this);
findViewById(R.id.btn_8).setOnClickListener(this);
findViewById(R.id.btn_9).setOnClickListener(this);
findViewById(R.id.btn_divide).setOnClickListener(this);
findViewById(R.id.btn_multi).setOnClickListener(this);
findViewById(R.id.btn_plus).setOnClickListener(this);
findViewById(R.id.btn_sub).setOnClickListener(this);
findViewById(R.id.btn_equal).setOnClickListener(this);
findViewById(R.id.btn_clear).setOnClickListener(this);
findViewById(R.id.btn_back).setOnClickListener(this);
findViewById(R.id.btn_equal).setOnClickListener(this);
findViewById(R.id.btn_dot).setOnClickListener(this);
}
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_0:
num_down("0");break;
case R.id.btn_1:
num_down("1");break;
case R.id.btn_2:
num_down("2");break;
case R.id.btn_3:
num_down("3");break;
case R.id.btn_4:
num_down("4");break;
case R.id.btn_5:
num_down("5");break;
case R.id.btn_6:
num_down("6");break;
case R.id.btn_7:
num_down("7");break;
case R.id.btn_8:
num_down("8");break;
case R.id.btn_9:
num_down("9");break;
case R.id.btn_plus:
operator_down("+");break;
case R.id.btn_sub:
operator_down("-");break;
case R.id.btn_divide:
operator_down("÷");break;
case R.id.btn_multi:
operator_down("×");break;
case R.id.btn_clear:
isDotDown = false;
isOperateDown = false;
txt_edit.setText("0");
txt_result.setText("");
break;
case R.id.btn_back: {
String strEdit = txt_edit.getText().toString();
int length = strEdit.length();
if (Pattern.matches("^=[0-9].*", strEdit)) {
txt_edit.setText("0");
txt_result.setText("");
} else {
if (length > 0) {
String word = strEdit.substring(length - 1, length);
if(word.equals("."))
isDotDown = false;
if(word.equals("+") || word.equals("-") || word.equals("×") || word.equals("÷"))
isOperateDown = false;
txt_edit.setText(strEdit.substring(0, length - 1));
}
}
break;
}
case R.id.btn_dot: {
String strEdit = txt_edit.getText().toString();
if (!isDotDown) {
isDotDown = true;
if(Pattern.matches("^=[0-9].*", strEdit))
strEdit = "0";
txt_edit.setText(strEdit + ".");
}
break;
}
case R.id.btn_equal:
equal();break;
}
}
//
private void num_down(String num) {
String strEdit = txt_edit.getText().toString();
isOperateDown = false;
if (strEdit.equals("0") || Pattern.matches("^=[0-9].*", strEdit)) {
txt_edit.setText(num);
txt_result.setText("");
} else {
txt_edit.setText(strEdit + num);
}
}
//
private void operator_down(String operator) {
if(!isOperateDown) {
String strEdit = txt_edit.getText().toString();
isOperateDown = true;
isDotDown = false;
if(Pattern.matches("^=[0-9].*", strEdit))
strEdit = strEdit.substring(1, strEdit.length());
txt_edit.setText(strEdit + operator);
}
}
private void equal() {
String strEdit = txt_edit.getText().toString();
int length = strEdit.length();
if(!Pattern.matches("^=[0-9].*", strEdit))
{
txt_result.setText(strEdit);
if(Pattern.matches(".*[\\+\\-\\×\\÷\\.]$", strEdit)) {
strEdit = strEdit.substring(0, length - 1);
}
String postfixExp = getPostfixExp(strEdit);
txt_edit.setText("=" + calPostfix(postfixExp));
}
}
//
private String getPostfixExp(String str) {
String postfix = "";
String numString = ""; // String
Stack numStack = new Stack();
Stack opStack = new Stack();
for(int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
if(Character.isDigit(ch) || ch == '.') { // ch .
numString += String.valueOf(ch); // . numString,
} else { //ch
if(numString.length() > 0) {
numStack.push(numString);//
numString = ""; // , numString
}
opPush(opStack, numStack, ch);
}
}
// numString , ,
if(numString.length() > 0)
numStack.push(numString);
// ,
while(!opStack.empty()) {
numStack.push(opStack.pop());
}
//
// , , , reverse
// ,
while(!numStack.empty()) {
opStack.push(numStack.pop());
}
while(!opStack.empty()) {
postfix = postfix + String.valueOf(opStack.pop()) + " ";
}
return postfix;
}
//
private String calPostfix(String str) {
String result = "";
Stack numStack = new Stack();
for(int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
if(ch == ' ') {
//
if(result.length() > 0 && (result.equals("+") || result.equals("-") || result.equals("×") || result.equals("÷")))
{
double num = 0;
double secondNum = Double.parseDouble(String.valueOf(numStack.pop()));
double firstNum = Double.parseDouble(String.valueOf(numStack.pop()));
switch (result) {
case "+":
num = firstNum + secondNum;break;
case "-":
num = firstNum - secondNum;break;
case "×":
num = firstNum * secondNum;break;
case "÷":
num = firstNum / secondNum;break;
}
numStack.push(num);
}
else if(result.length() > 0) {
numStack.push(result);
}
result = "";
} else {
result += String.valueOf(ch);
}
}
return BigDecimal.valueOf(Double.valueOf(String.valueOf(numStack.pop()))).stripTrailingZeros().toPlainString();
}
//
private int getOpWeight(char ch) {
// + - 1
if(ch == '+' || ch == '-') return 1;
//× ÷ 2
if(ch == '×' || ch == '÷') return 4;
return -1;
}
//
private void opPush(Stack opStack, Stack numStack, char ch) {
if(canOpPush(opStack, ch)) { //
opStack.push(ch); //true
} else { //false( <= )
//
numStack.push(String.valueOf(opStack.pop()));
// , >=
opPush(opStack, numStack, ch);
}
}
//
private Boolean canOpPush(Stack opStack, char ch) {
// , true; , true
if(opStack.empty() || (getOpWeight(ch) > getOpWeight(String.valueOf(opStack.peek()).charAt(0))))
return true;
return false; // false
}
}