一、應用介紹
安卓計算器:
實現功能:
(1)能實現基本的加減乘除運算、回退和清空輸入。
(2)豎屏時能實現基本的加減乘除運算、回退和清空輸入。橫屏時變為科學計算器,實現函數計算、進制換算等功能。
(3)數字按鍵依照電話撥號鍵盤順序排列。
(4)點擊菜單可對計算器相關特性進行配置。
(5)輸入計算公式,按等號鍵輸出計算結果。
(6)公式輸入和結果顯示區應支持長按彈出復制、粘貼功能。
(7)使用計算器過程中應不彈出軟鍵盤。
(8)可以通過進度條實時調整計算結果保留的小數點后位數,或者通過音量鍵完成同樣的效果。
(9)實現附加功能:三角函數、階乘、XY、√(Y&X)及括號,如sin(90)。
(10)輸入表達式按優先級計算,按等號輸出結果。
(11)對常用鍵布局需考慮特殊處理。
(12)處理精度和容錯問題:
a.1/3+1/3+1/3;
2.1+0.001;
1.1-1.001;
1/0、1/(1-1)和1/sin(0)等;
3/2;
對有附加功能的需要處理特殊值,如:√(2&-1) 等。
二、 運行截圖
豎屏時
橫屏時
主要代碼
MainActivity.java
public class MainActivity extends AppCompatActivity {String formula = "";//公式方程Boolean zeroMark = true; //允許輸入一個0Boolean zeroCon = false;//允許持續輸入0Boolean docMark = true;// . 可以輸入 .Boolean resultMark = false; //結果是否計算出Boolean transformMark = false; //是否進行二進制轉化Boolean errorMark = false;Boolean numAndOpMark = true;int color = 0xffffffff;private static final String REGEX = "^\\d+$";//all is numint precision = 3; //保留小數點位數@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR); //屏幕旋轉setContentView(R.layout.col);EditText show = findViewById(R.id.show);show.setText("");show.setSelectAllOnFocus(true); // 設置長按時選擇全部calculator();}public void calculator() {disableShowInput(); // 不讓彈出軟鍵盤EditText show = findViewById(R.id.show);Button dot = findViewById(R.id.dot);Button zero = findViewById(R.id.zero);Button one = findViewById(R.id.one);Button two = findViewById(R.id.two);Button three = findViewById(R.id.three);Button four = findViewById(R.id.four);Button five = findViewById(R.id.five);Button six = findViewById(R.id.six);Button seven = findViewById(R.id.seven);Button eight = findViewById(R.id.eight);Button nine = findViewById(R.id.nine);Button add = findViewById(R.id.add);Button sub = findViewById(R.id.sub);Button division = findViewById(R.id.division);Button back = findViewById(R.id.back);Button AC = findViewById(R.id.AC);Button mul = findViewById(R.id.mul);Button eval = findViewById(R.id.eval);Button percent = findViewById(R.id.percent);Button sin = findViewById(R.id.sin);Button power = findViewById(R.id.power);Button factorial = findViewById(R.id.factorial); //階乘Button square = findViewById(R.id.square); //開根號Button brackets = findViewById(R.id.brackets);Button transform = findViewById(R.id.transform);dot.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {doNum(".");}});zero.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {doNum("0");}});one.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {doNum("1");}});two.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {doNum("2");}});three.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {doNum("3");}});four.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {doNum("4");}});five.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {doNum("5");}});six.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {doNum("6");}});seven.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {doNum("7");}});eight.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {doNum("8");}});nine.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {doNum("9");}});add.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {doOp("+");}});sub.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {doOp("-");}});mul.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {doOp("×");}});division.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {doOp("÷");}});AC.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {reSetStatus();show.setText("");}});back.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {if (formula.length() > 0) {if (!formula.contains("(D->B)")) {if (lastStr().equals(".")) {docMark = true;}formula = formula.substring(0, formula.length() - 1);} else {formula = formula.replace("(D->B)", "");numAndOpMark = true;transformMark = false;}show.setText(formula);show.setTextColor(0xff000000);}}});eval.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {try {String result = "";if (transformMark) { // 先判斷是不是要進行二進制轉化doTransform();return;}delLastOp(); // 如果式子是 4- 進行計算,我們打算將-號去掉,結果為4try {result = Result.getRes(formula) + ""; //將計算式放入getRes函數中進行計算} catch (Exception e) {show.setText(e.getMessage()); //getRes中拋出的異常進行抓取并顯示show.setTextColor(0xffff0000);errorMark = true;return;}System.out.println(result + "result");if (result.contains("E") && !result.contains("E-")) {// 結果使用了科學計數法表示,我們要根據情況進行處理show.setText(result);Toast toast = Toast.makeText(getApplicationContext(), "數值太大,已用科學計數法表示", Toast.LENGTH_SHORT);toast.show();return;}
// String intPart;// if (result.length() > 12) {if (result.contains("E-")) {BigDecimal decimal = new BigDecimal(result);result = decimal.toPlainString();}if (result.length() > 12){result = result.substring(0, 11);}result = doPrecision(result); //進行精讀修改show.setText(result);reSetStatus();formula = result;resultMark = true;docMark = true;} catch (Exception e) {e.printStackTrace();}}});percent.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {if (formula.length() > 0) {if (!numAndOpMark) {return;}formula = "(" + formula + ")*0.01";try {show.setText(doEval(formula));formula = doEval(formula);} catch (Exception e) {show.setText(e.getMessage());}}}});sin.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {if (!numAndOpMark) {return;}formula = formula + "sin(";show.setText(formula);}});square.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {if (!numAndOpMark) {return;}formula = formula + "v(";show.setText(formula);}});power.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {if (!numAndOpMark) {return;}formula = formula + "^";show.setText(formula);}});factorial.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {if (!numAndOpMark) {return;}try {if (formula.contains(".") ){Toast toast = Toast.makeText(getApplicationContext(), "小數不可以階乘", Toast.LENGTH_SHORT);toast.show();return;}if (Result.getRes(formula) < 171) {formula = formula + "!";show.setText(formula);} else {Toast toast = Toast.makeText(getApplicationContext(), "數值太大!", Toast.LENGTH_SHORT);toast.show();show.setTextColor(0xffff0000);resultMark = true;}} catch (Exception e) {e.printStackTrace();}}});brackets.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {if (!numAndOpMark) {return;}if (lastIsNum() || lastStr().equals(")")) {formula = formula + ")";} else {formula = formula + "(";}show.setText(formula);}});transform.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {if (formula.matches(REGEX)) {formula = formula + "(D->B)";show.setText(formula);transformMark = true;numAndOpMark = false;}}});}public String doPrecision(String result) {System.out.println(result + "rep");String tail = result.split("\\.")[1];String pre = result.split("\\.")[0];int deltaPre = precision - tail.length();if (deltaPre > 0) {for (int i = 0; i < deltaPre; i++) {result = result + "0";}} else if (deltaPre < 0) {double doubleResult = Double.parseDouble(result);BigDecimal bigResult = new BigDecimal(doubleResult);result = bigResult.setScale(precision, BigDecimal.ROUND_HALF_UP).toString();}System.out.println(result + "pre");return result;}public void reSetStatus() { //將各個監控狀態設為初始狀態EditText show = findViewById(R.id.show);show.setTextColor(0xff000000);formula = "";zeroMark = true;zeroCon = false;docMark = true;resultMark = false;transformMark = false;numAndOpMark = true;}@SuppressLint("SetTextI18n")public void doTransform() { //二進制轉化方法EditText show = findViewById(R.id.show);transformMark = false;String num = formula.split("\\(")[0];show.setText(Integer.toBinaryString(Integer.parseInt(num)) + "B");resultMark = true;docMark = true;}public String lastStr() {if (formula.length() > 0) {return formula.charAt(formula.length() - 1) + "";} else {return "";}} //返回字符的最后一個字符public String doEval(String formula) throws Exception { //做簡單的計算方法ScriptEngineManager manager = new ScriptEngineManager();ScriptEngine se = manager.getEngineByName("js");return se.eval(formula) + "";}public Boolean lastIsNum() { //最后一位是不是數字if (formula.length() == 0) {return false;} else {char lastChar = formula.charAt(formula.length() - 1);return lastChar > 47 && lastChar < 58;}}public Boolean lastIsOp() { //最后一位字符是不是操作符return isOp(lastStr());}public Boolean isOp(String str) { //傳遞的參數是不是操作符return (str.equals("+") || str.equals("×")|| str.equals("÷") || str.equals("-"));}public void doNum(String num) {EditText show = findViewById(R.id.show);show.setTextColor(0xff000000);int length = formula.length();if (!numAndOpMark) { //當使用(D->B)后我們不再允許進行任何符號的輸入return;}if (errorMark) { //是否出錯reSetStatus();errorMark = false;}if (resultMark) { //結果是否已算出formula = "";resultMark = false;}if (num.equals(".")) { //輸的字符是不是點 .000000000000if (docMark) { // && !isOp(lastStr())formula = formula + '.';show.setText(formula);docMark = false;zeroCon = true;}return;}if (num.equals("0")) { //是不是0? 00000000000if (zeroCon || zeroMark) {formula = formula + '0';}show.setText(formula);zeroMark = false;return;}if (formula.startsWith("0") && length == 1) { //0的特殊情況 09 -> 9formula = "";}if (length > 2 && formula.endsWith("0") && isOp(formula.charAt(length - 2) + "")) {formula = formula.substring(0, length - 1); // 0的特殊情況 23 + 09 -> 23 + 9}formula = formula + num; //加入計算式zeroCon = true;show.setText(formula);}public void doOp(String op) {EditText show = findViewById(R.id.show);show.setTextColor(0xff000000);if (!numAndOpMark || lastStr().equals(".")) {return;}if (errorMark) { //是否有錯誤 - is okreSetStatus();errorMark = false;}if (resultMark) { //結果是否計算出formula = show.getText().toString();resultMark = false;}if ((lastStr().equals("÷") || lastStr().equals("×")) && op.equals("-")) {addOp(op);return;}if (formula.contains("×-") || formula.contains("÷-")) {formula = formula.substring(0, formula.length() - 2);}if (formula.length() == 1 && lastStr().equals("-")) { // 只有一個減號,不允許輸任何操作符return;}if (formula.length() == 0 || lastStr().equals("(")) { //1+(?=-if (op.equals("-")) { // 第一個輸入的字符是不是-addOp(op);}return;}if (lastIsOp() && formula.length() > 0) { //若最后一個字符已經時操作符,那要替換掉舊的替換符formula = formula.substring(0, formula.length() - 1);}addOp(op); //如果沒有以上特殊情況,則加到計算式里}public void addOp(String op) { // 輸入操作符時大部分的重復工作進行封裝EditText show = findViewById(R.id.show);formula = formula + op;docMark = true;zeroMark = true;zeroCon = false;show.setText(formula);}//==================================================================================@SuppressLint("SetTextI18n")@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) { //設置精度(通過音量鍵)TextView info = findViewById(R.id.info);switch (keyCode) {case KeyEvent.KEYCODE_VOLUME_DOWN:if (precision > 1) {precision--;info.setText("保留" + precision + "位");Toast.makeText(this, "保留" + precision + "位", Toast.LENGTH_SHORT).show();} else {Toast.makeText(this, "至少保留1位", Toast.LENGTH_SHORT).show();}break;case KeyEvent.KEYCODE_VOLUME_UP:if (precision < 10) {precision++;Toast.makeText(this, "保留" + precision + "位", Toast.LENGTH_SHORT).show();info.setText("保留" + precision + "位");} else {Toast.makeText(this, "至多保留10位", Toast.LENGTH_SHORT).show();}break;}return super.onKeyDown(keyCode, event);}@SuppressLint("SetTextI18n")@Overridepublic void onConfigurationChanged(Configuration newConfig) { //橫豎屏切換時進行設置@SuppressLint("CutPasteId") EditText show1 = findViewById(R.id.show);color = show1.getCurrentTextColor();formula = show1.getText().toString(); //如果你是復制進去的式子,那必須先從show中得到式子// TODO Auto-generated method stubsuper.onConfigurationChanged(newConfig);//啟動時默認是豎屏if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {setContentView(R.layout.col);@SuppressLint("CutPasteId") EditText show = findViewById(R.id.show);show.setText(formula);show.setTextColor(color);calculator();}//切換就是橫屏else if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {setContentView(R.layout.row);@SuppressLint("CutPasteId") EditText show = findViewById(R.id.show);TextView info = findViewById(R.id.info);info.setText("保留" + precision + "位");show.setText(formula);show.setTextColor(color);calculator();}}//========================================================================================@Overridepublic boolean onCreateOptionsMenu(Menu menu) { //生成菜單項MenuInflater inflater = new MenuInflater(this);inflater.inflate(R.menu.menu, menu);return super.onCreateOptionsMenu(menu);}@SuppressLint("NonConstantResourceId")@Override //菜單項無所謂public boolean onOptionsItemSelected(MenuItem item) {EditText show = findViewById(R.id.show);//先判斷點擊的是哪個idswitch (item.getItemId()) {case R.id.font_10:show.setTextSize(10 * 2);break;case R.id.font_12:show.setTextSize(12 * 2);break;case R.id.font_14:show.setTextSize(14 * 2);break;case R.id.font_16:show.setTextSize(16 * 2);break;case R.id.font_18:show.setTextSize(18 * 2);break;case R.id.blue:show.setTextColor(Color.BLUE);break;case R.id.red:show.setTextColor(Color.RED);break;case R.id.green:show.setTextColor(Color.GREEN);break;}return super.onOptionsItemSelected(item);}//======================================================================================public void disableShowInput() { //設置鍵盤不可見EditText show = findViewById(R.id.show);Class<EditText> cls = EditText.class;Method method;try {method = cls.getMethod("setShowSoftInputOnFocus", boolean.class);method.setAccessible(true);method.invoke(show, false);} catch (Exception e) {//TODO: handle exception}try {method = cls.getMethod("setSoftInputShownOnFocus", boolean.class);method.setAccessible(true);method.invoke(show, false);} catch (Exception e) {//TODO: handle exception}}//=============================================================================public void delLastOp() { //寫個小遞歸,后來想想好像用不到,但懶得改了if (isOp(formula.charAt(formula.length() - 1) + "") || lastStr().equals(".")) {formula = formula.substring(0, formula.length() - 1);delLastOp();}}
ArrayStack.java
class ArrayStack {private int maxSize; // 棧的大小private double[] stack; // 數組,數組模擬棧,數據就放在該數組private int top = -1;// top表示棧頂,初始化為-1//構造器public ArrayStack(int maxSize) {this.maxSize = maxSize;stack = new double[this.maxSize];}//增加一個方法,可以返回當前棧頂的值, 但是不是真正的poppublic double peek() {return stack[top];}//棧滿public boolean isFull() {return top == maxSize - 1;}//棧空public boolean isEmpty() {return top == -1;}//入棧-pushpublic void push(double value) {//先判斷棧是否滿if (isFull()) {System.out.println("表達式錯誤");return;}top++;stack[top] = value;}//出棧-pop, 將棧頂的數據返回public double pop() {//先判斷棧是否空if (isEmpty()) {//拋出異常throw new RuntimeException("表達式錯誤");}double value = stack[top];top--;return value;}//顯示棧的情況[遍歷棧], 遍歷時,需要從棧頂開始顯示數據public void list() {if (isEmpty()) {System.out.println("表達式錯誤");return;}//需要從棧頂開始顯示數據for (int i = top; i >= 0; i--) {System.out.printf("stack[%d]=%d\n", i, stack[i]);}}//返回運算符的優先級,優先級是程序員來確定, 優先級使用數字表示//數字越大,則優先級就越高.public int priority(int oper) {if (oper == '*' || oper == '/') {return 1;} else if (oper == '+' || oper == '-') {return 0;} else if (oper == '^'||oper == '#') {return 2;} else if (oper == '!' || oper == 'v' || oper == '%') {return 3;} else if (oper == 's' || oper == 't' || oper == 'c') {return 4;} else {return -1; // 假定目前的表達式只有 +, - , * , /}}//判斷是不是一個運算符public boolean isNum(char val) {return '0' <= val && val <= '9';}//判斷是不是一個運算符public boolean isOper(char val) {return val == '+' || val == '-' || val == '*' || val == '/' || val == '#' || val == '^' || val == '%' || val == 's' || val == 'c' || val == 't' || val == '!' || val == 'v';}//判斷是不是 (public boolean isLeftBrackets(char val) {return val == '(';}//判斷是不是 )public boolean isRightBrackets(char val) {return val == ')';}//判斷是不是 .public boolean isPoint(char val) {return val == '.';}//判斷是不是 (public boolean isTrigonometric(char val) {return val == 's';}//計算方法public double cal(double num1, double num2, int oper) {double res = 0; // res 用于存放計算的結果switch (oper) {case '+':res = num1 + num2;break;case '-':res = sub(num2,num1);// 注意順序break;case '*':res = num1 * num2;break;case '/':if (num1 == 0) {throw new RuntimeException("定義域錯誤");}res = num2 / num1;break;case '^':res = Math.pow(num2, num1);break;default:break;}return res;}/*** 三角函數運算、階乘運算或者是開根操作** @param num1* @param oper* @return*/public double mixedOperation(double num1, int oper) {double res = 1; // res 用于存放計算的結果switch (oper) {case 's':res = Math.sin(num1 * Math.PI / 180);break;case 'c':res = Math.cos(num1 * Math.PI / 180);break;case 't':res = Math.tan(num1 * Math.PI / 180);break;case '!':for (int i = 1; i <= num1; i++) {res *= i;}break;case 'v':if (num1 < 0) {throw new RuntimeException("定義域錯誤");}res = Math.sqrt(num1);break;case '%':res = num1 / 100;break;case '#':res = -num1;break;default:break;}return res;}double sub(double x, double y) {BigDecimal initResult = new BigDecimal(x - y); //計算初步結果String temp = initResult.toString();if (temp.contains(".")){temp = temp + "00000000000000000000";}else {temp = temp + ".00000000000000000000";}int lengthOfInt = getLengthOfInt(x, y); //結果整形位數int lengthOfDec = Math.max(getLengthOfDecimal(x), getLengthOfDecimal(y));int count = lengthOfInt + lengthOfDec + 2; //最后輸出的位數 = 整形位數+小數位數+小數點位數+1(四舍五入舍去)double tempResult = Double.parseDouble(temp.substring(0, count)); //將String轉換成double,并截取多一位用于四舍五入double power = Math.pow(10, lengthOfDec); //求10的幾次方用來四舍五入double finalResult = (double) (Math.round(tempResult * power)) / power; //四舍五入Log.i("result", x + "-" + y + "=" + finalResult);//此處的長度取決于小數點后面位數大的return finalResult;}int getLengthOfInt(double x, double y) {int lengthOfInt;int intX = (int) x; //x的整數部分int intY = (int) y; //y的整數部分lengthOfInt = String.valueOf(intX - intY).length(); //結果整形部分的位數 = 相減后整形的位數return lengthOfInt;}int getLengthOfDecimal(double x) {return String.valueOf(x).split("\\.")[1].length(); //計算x小數點后面的位數}
public class Result {public static double getRes(String expression) {System.out.println(expression.length());expression = expression.replace("sin", "s");expression = expression.replace("÷", "/");expression = expression.replace("×", "*");ArrayStack stack=new ArrayStack(20);String exp = "";int count = 0;char[] chars = expression.toCharArray();while (count < chars.length) {if (count == 0 && chars[count] == '-') {chars[count] = '#';}if (count >= 1 && chars[count] == '-' && chars[count - 1] == '(') {chars[count] = '#';}if (count >= 1 && chars[count] == '-' && stack.priority(chars[count-1])>stack.priority(chars[count])) {chars[count] = '#';}exp += chars[count];count++;}expression=exp;//創建兩個棧,數棧,一個符號棧ArrayStack numStack = new ArrayStack(20);ArrayStack operatorStack = new ArrayStack(20);//定義需要的相關變量int index = 0;//用于掃描double num1 = 0;double num2 = 0;int oper = 0;double res = 0;char ch = ' '; //將每次掃描得到char保存到chString keepNum = ""; //用于拼接 多位數//開始while循環的掃描expressionwhile (true) {//依次得到expression 的每一個字符ch = expression.substring(index, index + 1).charAt(0);//判斷ch是什么,然后做相應的處理if (operatorStack.isLeftBrackets(ch)) { //如果是左括號//直接入符號棧..operatorStack.push(ch);} else if (operatorStack.isRightBrackets(ch)) { //如果是右括號while (operatorStack.peek() != '(') { //循環直到能夠到達 '(' 處oper = (int) operatorStack.pop();if (oper == 's' ||oper == '!' ||oper == 'v' ||oper == '#' ||oper == '%') { //如果棧頂為三角函數、階乘或者是開根num1 = numStack.pop();res = numStack.mixedOperation(num1, oper);//把運算的結果如數棧numStack.push(res);} else {num1 = numStack.pop();num2 = numStack.pop();res = operatorStack.cal(num1, num2, oper);//把運算的結果如數棧numStack.push(res);}}//然后將當前棧頂的操作符出符號棧----其實也就是 '(' 出棧operatorStack.pop();} else if (operatorStack.isOper(ch)) { //如果是運算符if (operatorStack.isEmpty() || operatorStack.peek() == '(') {//如果符號棧為空,或者棧頂為'('operatorStack.push(ch);} else if (operatorStack.priority(ch) > operatorStack.priority((int) operatorStack.peek())) {//如果當前優先級比棧頂優先級高,直接入符號棧.operatorStack.push(ch);} else {while (!operatorStack.isEmpty() &&(operatorStack.priority(ch) <= operatorStack.priority((int) operatorStack.peek()))) {oper = (int) operatorStack.pop();if (!operatorStack.isEmpty() && (operatorStack.peek() == '!' ||operatorStack.peek() == 's' ||operatorStack.peek() == 'v' ||operatorStack.peek() == '#' ||operatorStack.peek() == '%')) {num1 = numStack.pop();res = numStack.mixedOperation(num1, oper);numStack.push(res);//入棧} else {if (oper == 's' ||oper == '!' ||oper == 'v' ||oper == '#' ||oper == '%') { //如果棧頂為三角函數、階乘或者是開根num1 = numStack.pop();res = numStack.mixedOperation(num1, oper);//把運算的結果如數棧numStack.push(res);} else {num1 = numStack.pop();num2 = numStack.pop();res = numStack.cal(num1, num2, oper);//把運算的結果如數棧numStack.push(res);}}}//然后將當前的操作符入符號棧operatorStack.push(ch);}} else if (operatorStack.isPoint(ch) || operatorStack.isNum(ch)) { //如果是數或者是小數點,則直接入數棧//numStack.push(ch - 48); // "1+3" '1' => 1//1. 當處理多位數時,不能發現是一個數就立即入棧,因為可能是多位數//2. 在處理數,需要向expression的表達式的index 后再看一位,如果是數就進行掃描,如果是符號才入棧//3. 因此我們需要定義一個變量 字符串,用于拼接//處理多位數keepNum += ch;//如果ch已經是expression的最后一位,就直接入棧if (index == expression.length() - 1) {numStack.push(Double.parseDouble(keepNum));} else {//判斷下一個字符是不是數字,如果是數字,就繼續掃描,如果是運算符,則入棧//注意是看后一位,不是index++if (operatorStack.isOper(expression.substring(index + 1, index + 2).charAt(0))|| operatorStack.isRightBrackets(expression.substring(index + 1, index + 2).charAt(0))) {//如果后一位是運算符,則入棧 keepNum = "1" 或者 "123"numStack.push(Double.parseDouble(keepNum));//最后keepNum必須清空keepNum = "";}}} else if (!operatorStack.isEmpty() && (operatorStack.peek() == 's' ||operatorStack.peek() == '!' ||operatorStack.peek() == 'v' ||operatorStack.peek() == '#' ||operatorStack.peek() == '%')) { //如果棧頂為三角函數算式、開根或者是階乘oper = (int) operatorStack.pop();num1 = numStack.pop();res = numStack.mixedOperation(num1, oper);//把運算的結果入數棧numStack.push(res);}//讓index + 1, 并判斷是否掃描到expression最后.index++;if (index >= expression.length()) {break;}}//當表達式掃描完畢,就順序的從 數棧和符號棧中pop出相應的數和符號,并運行.while (true) {//如果符號棧為空,則計算到最后的結果, 數棧中只有一個數字【結果】if (operatorStack.isEmpty()) {break;}if (operatorStack.peek() == 's' ||operatorStack.peek() == '!' ||operatorStack.peek() == 'v' ||operatorStack.peek() == '#' ||operatorStack.peek() == '%') { //如果棧頂為三角函數算式oper = (int) operatorStack.pop();num1 = numStack.pop();res = numStack.mixedOperation(num1, oper);numStack.push(res);//入棧} else {num1 = numStack.pop();num2 = numStack.pop();oper = (int) operatorStack.pop();res = numStack.cal(num1, num2, oper);numStack.push(res);//入棧}}//將數棧的最后數,pop出,就是結果double res2 = numStack.pop();System.out.println(res2+"ll");return res2;}
求點贊+關注偶
總結
以上是生活随笔為你收集整理的心心念念的安卓简单和多功能计算器来了的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。