android 計算器

1、核心:

(1)計算器的每一次輸入要檢查合法性

(2)計算的核心是把從文本編輯框獲得的內容進行分離,將數字壓入數字棧,符號進行優先級判斷後壓入符號棧,然後依次取出運算得到結果。


(3)計算流程圖(由於電腦之前重裝了,沒有億圖,流程圖不多就用寫的了)


(4)重要代碼

1、這個函數是對輸入的運算式進行檢查,如果輸入的有錯誤,就進行提示,並且將輸入框鎖定。

 (代碼註釋比較多,這裏就不多說了)

private void TipChecker(String tipcommand1,String tipcommand2){

    //Tipcode1表示數據類型,Tipcode2表示名詞類型解釋

    int Tipcode1=0,Tipcode2=0;

    //表示命令類型

    int tiptype1=0,tiptype2=0;

    //括號數

    int bracket=0;

    //+-*/^)根號 不能作爲第一位

if(tipcommand1.compareTo("#")==0&&(tipcommand2.compareTo("÷")==0||tipcommand2.compareTo("")==0||tipcommand2.compareTo("+")==0||tipcommand2.compareTo(")")==0||tipcommand2.compareTo("")==0||tipcommand2.compareTo("^")==0)){Tipcode1=-1;}

 //定義存儲字符串中最後一位的類型

 elseif(tipcommand1.compareTo("#")!=0){if(tipcommand1.compareTo("(")==0){tiptype1=1;}elseif(tipcommand1.compareTo(")")==0){tiptype1=2;}else if(tipcommand1.compareTo(".")==0){tiptype1=3;}else if("0123456789".indexOf(tipcommand1)!=-1){tiptype1=4;}

     else if("+-×÷".indexOf(tipcommand1)!=-1){tiptype1=5;}else if("^".indexOf(tipcommand1)!=-1){tiptype1=6;}else if("sincostanlnlogn!".indexOf(tipcommand1)!=-1){tiptype1=7;}

     //定義欲輸入的按鍵類型

     if(tipcommand2.compareTo("(")==0){tiptype2=1;}else if(tipcommand2.compareTo(")")==0){tiptype2=2;}else if(tipcommand2.compareTo(".")==0){tiptype2=3;}else if("0123456789".indexOf(tipcommand1)!=-1){tiptype2=4;}

     else if("+-×÷".indexOf(tipcommand2)!=-1){tiptype2=5;}else if("^".indexOf(tipcommand2)!=-1){tiptype2=6;}else if("sincostanlnlogn!".indexOf(tipcommand2)!=-1){tiptype2=7;}

     switch(tiptype1){

     case 1://左括號後面直接接右括號,“+*/(符號不算),或者“根號^

     if(tiptype2==2||(tiptype2==5&&tipcommand2.compareTo("-")!=0)||tiptype2==6) Tipcode1=1; break;

     case 2://右括號後面接左括號、數字、“+-*/sin^...

     if(tiptype2==1||tiptype2==3||tiptype2==4||tiptype2==7) Tipcode1=2; break;

     case 3://"."後面接左括號或者sincon...

     if(tiptype2==1||tiptype2==7) Tipcode1=3;

     //連續輸入兩個“.

     if(tiptype2==3) Tipcode1=8; break;

     case 4://數字後面直接接左括號或者“sincon...

     if(tiptype2==1||tiptype2==7) Tipcode1=4;break;

     case 5://+-×÷後面直接接右括號,+-×÷根號^

     if(tiptype2==2||tiptype2==5||tiptype2==6) Tipcode1=5;break;

     case 6://根號^後面直接接右括號,+-×÷根號^以及“sincos...

     if(tiptype2==2||tiptype2==5||tiptype2==6||tiptype2==7) Tipcode1=6;break;

     case 7://sincos...後面直接接右括號“+-*/根號^”以及sincos

     if(tiptype2==2||tiptype2==5||tiptype2==6||tiptype2==7) Tipcode1=7;break;

     }

     }//(tipcommand1.compareTo("#")!=0)

         //檢測小數點的重複性,Tipcondel=0,表明滿足前面的規則

         if(Tipcode1==0 &&tipcommand2.compareTo(".")==0){

         int tip_point=0;

         for(int i=0;i<tip_i;i++){

         if(Tipcommand[i].compareTo(".")==0)

         tip_point++;

             //若出現以下幾個運算符之一,小數點計數清零

             if(Tipcommand[i].compareTo("sin")==0||Tipcommand[i].compareTo("cos")==0||Tipcommand[i].compareTo("tan")==0||

             Tipcommand[i].compareTo("log")==0||Tipcommand[i].compareTo("ln")==0||Tipcommand[i].compareTo("n!")==0

             ||Tipcommand[i].compareTo("")==0||Tipcommand[i].compareTo("^")==0||Tipcommand[i].compareTo("+")==0

             ||Tipcommand[i].compareTo("-")==0||Tipcommand[i].compareTo("×")==0||Tipcommand[i].compareTo("÷")==0

             ||Tipcommand[i].compareTo("(")==0||Tipcommand[i].compareTo(")")==0){tip_point=0;}

         }

         tip_point++;

         //若小數點計數大於1,表明小數點重複了

         if(tip_point>1){Tipcode1 = 8;}

         }//if(Tipcode1==0 &&tipcommand2.compareTo(".")==0){}

         //檢測右括號是否匹配

         if(Tipcode1==0 &&tipcommand2.compareTo(")")==0){

         int tip_right_bracket=0;

         for(int i=0;i<tip_i;i++){if(Tipcommand[i].compareTo("(")==0)tip_right_bracket++;if(Tipcommand[i].compareTo(")")==0)tip_right_bracket--;}

         if(tip_right_bracket==0){Tipcode1=10;}

         }

         //檢測輸入=的合法性

         if(Tipcode1==0 &&tipcommand2.compareTo("=")==0){

         int tip_bracket=0;

         for(int i=0;i<tip_i;i++){if(Tipcommand[i].compareTo("(")==0){tip_bracket++;}if(Tipcommand[i].compareTo(")")==0){tip_bracket--;}}

         //若大於0,表明左括號還有未比配的

         if(tip_bracket>0){Tipcode1=9;bracket=tip_bracket;}

         //若前一個字符是以下之一,表明=不合法

         else if(tip_bracket==0){if("^sincostanlnlogn!".indexOf(tipcommand1)!=-1){Tipcode1=6;}

         if("+-×÷".indexOf(tipcommand1)!=-1){Tipcode1=5;}}           

         }

         //顯示幫助和錯誤信息

         TipShow(bracket,Tipcode1,Tipcode2,tipcommand1,tipcommand2);

     }//private void TipChecker(String tipcommand1,String tipcommand2){}

2、計算部分的代碼

 

 

 public void process(String str) {

                    int weightPlus = 0, topOp = 0,

                    topNum = 0, flag = 1, weightTemp = 0;

                    //weightPlus爲同一()下的基本優先級,weightTemp臨時記錄優先級的變化

                    //topOp爲weight[],operator[]的計數器;topNum爲number[]的計數器

                    //flag爲正負數的計數器,1爲正數,-1爲負數

                    int weight[];  //保存operator棧中運算符的優先級,以topOp計數

                    double number[];  //保存數字,以topNum計數

                    char ch, ch_gai, operator[];//operator[]保存運算符,以topOp計數

                    String num;//記錄數字,str以+-×÷()sctgl!√^分段,+-×÷()sctgl!√^字符之間的字符串即爲數字

                    weight = new int[MAXLEN];

                    number = new double[MAXLEN];

                    operator = new char[MAXLEN];

                    String expression = str;

                    StringTokenizer expToken = new StringTokenizer(expression,"+-×÷()sctgl!√^");

                    int i = 0;

                    while (i < expression.length()) {

                        ch = expression.charAt(i);

                        //判斷正負數

                        if (i == 0) {

                            if (ch == '-')

                             flag = -1;

                        } else if(expression.charAt(i-1) == '(' && ch == '-')

                         flag = -1;

                        //取得數字,並將正負符號轉移給數字

                        if (ch <= '9' && ch >= '0'|| ch == '.' || ch == 'E') {

                            num = expToken.nextToken();

                            ch_gai = ch;

                            Log.e("guojs",ch+"--->"+i);

                            //取得整個數字

                            while (i < expression.length() && 

                                    (ch_gai <= '9' && ch_gai >= '0'|| ch_gai == '.' || ch_gai == 'E')) 

                            {

                                ch_gai = expression.charAt(i++);

                                Log.e("guojs","i的值爲:"+i);

                            }

                            //將指針退回之前的位置

                            if (i >= expression.length()) i-=1; else {i-=2;}

                            if (num.compareTo(".") == 0) number[topNum++] = 0;

                            //將正負符號轉移給數字

                            else {

                                number[topNum++] = Double.parseDouble(num)*flag;

                                flag = 1;

                            }

                        }

                        //計算運算符的優先級

                        if (ch == '(') weightPlus+=4;

                        if (ch == ')') weightPlus-=4;

                        if (ch == '-' && flag == 1 || ch == '+' || ch == '×'|| ch == '÷' || 

                                ch == 's' ||ch == 'c' || ch == 't' || ch == 'g' || ch == 'l' || 

                                ch == '!' || ch == '√' || ch == '^') {

                            switch (ch) {

                             //+-的優先級最低,爲1

                                case '+':

                                case '-':

                                    weightTemp = 1 + weightPlus;

                                    break;

                                //x÷的優先級稍高,爲2

                                case '×':

                                case '÷':

                                    weightTemp = 2 + weightPlus;

                                    break;

                                //sincos之類優先級爲3

                                case 's':

                                case 'c':

                                case 't':

                                case 'g':

                                case 'l':

                                case '!':

                                    weightTemp = 3 + weightPlus;

                                    break;

                                //其餘優先級爲4

                                //case '^':

                                //case '√':

                                default:

                                    weightTemp = 4 + weightPlus;

                                    break;

                            }

                            //如果當前優先級大於堆棧頂部元素,則直接入棧

                            if (topOp == 0 || weight[topOp-1] < weightTemp) {

                                weight[topOp] = weightTemp;

                                operator[topOp] = ch;

                                topOp++;

                            //否則將堆棧中運算符逐個取出,直到當前堆棧頂部運算符的優先級小於當前運算符

                            }else {

                                 while (topOp > 0 && weight[topOp-1] >= weightTemp) {

                                    switch (operator[topOp-1]) {

                                     //取出數字數組的相應元素進行運算

                                        case '+':

                                            number[topNum-2]+=number[topNum-1];

                                            break;

                                        case '-':

                                            number[topNum-2]-=number[topNum-1];

                                            break;

                                        case '×':

                                            number[topNum-2]*=number[topNum-1];

                                            break;

                                        //判斷除數爲0的情況

                                        case '÷':

                                            if (number[topNum-1] == 0) {

                                                showError(1,str_old);

                                                return;

                                            }

                                            number[topNum-2]/=number[topNum-1];

                                            break;

                                        case '√':

                                            if(number[topNum-1] == 0 || (number[topNum-2] < 0 &&

                                                    number[topNum-1] % 2 == 0)) {

                                                showError(2,str_old);

                                                return;    

                                            } 

                                            number[topNum-2] = 

                                                Math.pow(number[topNum-2], 1/number[topNum-1]);

                                            break;

                                        case '^':

                                            number[topNum-2] = 

                                                Math.pow(number[topNum-2], number[topNum-1]);

                                            break;

                                        //計算時進行角度弧度的判斷及轉換

                                        //sin

                                        case 's':

                                            if(drg_flag == true) {

                                                number[topNum-1] = Math.sin((number[topNum-1]/180)*pi);

                                            } else {

                                                number[topNum-1] = Math.sin(number[topNum-1]);

                                            }

                                            topNum++;

                                            break;

                                        //cos

                                        case 'c':

                                            if(drg_flag == true) {

                                                number[topNum-1] = Math.cos((number[topNum-1]/180)*pi);

                                            } else {

                                                number[topNum-1] = Math.cos(number[topNum-1]);

                                            }

                                            topNum++;

                                            break;

                                        //tan

                                        case 't':

                                            if(drg_flag == true) {

                                                if((Math.abs(number[topNum-1])/90)%2 == 1) {

                                                    showError(2,str_old);

                                                    return;

                                                }

                                                number[topNum-1] = Math.tan((number[topNum-1]/180)*pi);

                                            } else {

                                                if((Math.abs(number[topNum-1])/(pi/2))%2 == 1) {

                                                    showError(2,str_old);

                                                    return;

                                                }

                                                number[topNum-1] = Math.tan(number[topNum-1]);

                                            }

                                            topNum++;

                                            break;

                                        //log

                                        case 'g':

                                            if(number[topNum-1] <= 0) {

                                                showError(2,str_old);

                                                return;    

                                            } 

                                            number[topNum-1] = Math.log10(number[topNum-1]);

                                            topNum++;

                                            break;

                                        //ln

                                        case 'l':

                                            if(number[topNum-1] <= 0) {

                                                showError(2,str_old);

                                                return;    

                                            } 

                                            number[topNum-1] = Math.log(number[topNum-1]);

                                            topNum++;

                                            break;

                                        //階乘

                                        case '!':

                                            if(number[topNum-1] > 170) {

                                                showError(3,str_old);

                                                return;    

                                            } else if(number[topNum-1] < 0) {

                                                showError(2,str_old);

                                                return;

                                            }

                                            number[topNum-1] = N(number[topNum-1]);

                                            topNum++;

                                            break;

                                    }

                                    //繼續取堆棧的下一個元素進行判斷

                                    topNum--;

                                    topOp--;

                                }

                                //將運算符如堆棧

                                weight[topOp] = weightTemp;

                                operator[topOp] = ch;

                                topOp++;

                            }

                        }

                        i++;

                    }

                    

                    //依次取出堆棧的運算符進行運算

                    while (topOp>0) {

                     //+-x直接將數組的後兩位數取出運算

                        switch (operator[topOp-1]) {

                        case '+':

                            number[topNum-2]+=number[topNum-1];

                            break;

                        case '-':

                            number[topNum-2]-=number[topNum-1];

                            break;

                        case '×':

                            number[topNum-2]*=number[topNum-1];

                            break;

                        //涉及到除法時要考慮除數不能爲零的情況

                        case '÷':

                            if (number[topNum-1] == 0) {

                                showError(1,str_old);

                                return;

                            }

                            number[topNum-2]/=number[topNum-1];

                            break;

                        case '√':

                            if(number[topNum-1] == 0 || (number[topNum-2] < 0 &&

                                    number[topNum-1] % 2 == 0)) {

                                showError(2,str_old);

                                return;    

                            } 

                            number[topNum-2] = 

                                Math.pow(number[topNum-2], 1/number[topNum-1]);

                            break;

                        case '^':

                            number[topNum-2] = 

                                Math.pow(number[topNum-2], number[topNum-1]);

                            break;

                        //sin

                        case 's':

                            if(drg_flag == true) {

                                number[topNum-1] = Math.sin((number[topNum-1]/180)*pi);

                            } else {

                                number[topNum-1] = Math.sin(number[topNum-1]);

                            }

                            topNum++;

                            break;

                        //cos

                        case 'c':

                            if(drg_flag == true) {

                                number[topNum-1] = Math.cos((number[topNum-1]/180)*pi);

                            } else {

                                number[topNum-1] = Math.cos(number[topNum-1]);

                            }

                            topNum++;

                            break;

                        //tan

                        case 't':

                            if(drg_flag == true) {

                                if((Math.abs(number[topNum-1])/90)%2 == 1) {

                                    showError(2,str_old);

                                    return;

                                }

                                number[topNum-1] = Math.tan((number[topNum-1]/180)*pi);

                            } else {

                                if((Math.abs(number[topNum-1])/(pi/2))%2 == 1) {

                                    showError(2,str_old);

                                    return;

                                }

                                number[topNum-1] = Math.tan(number[topNum-1]);

                            }

                            topNum++;

                            break;

                        //對數log

                        case 'g':

                            if(number[topNum-1] <= 0) {

                                showError(2,str_old);

                                return;    

                            } 

                            number[topNum-1] = Math.log10(number[topNum-1]);

                            topNum++;

                            break;

                        //自然對數ln

                        case 'l':

                            if(number[topNum-1] <= 0) {

                                showError(2,str_old);

                                return;    

                            } 

                            number[topNum-1] = Math.log(number[topNum-1]);

                            topNum++;

                            break;

                        //階乘

                        case '!':

                            if(number[topNum-1] > 170) {

                                showError(3,str_old);

                                return;    

                            } else if(number[topNum-1] < 0) {

                                showError(2,str_old);

                                return;

                            }

                            number[topNum-1] = N(number[topNum-1]);

                            topNum++;

                            break;

                        }

                        //取堆棧下一個元素計算

                        topNum--;

                        topOp--;

                    }

                    //如果是數字太大,提示錯誤信息

                    if(number[0] > 7.3E306) {

                        showError(3,str_old);

                        return;

                    }

                    //輸出最終結果

                    input.setText(String.valueOf(FP(number[0]))); 

                    tip.setText("計算完畢,要繼續請按歸零鍵 C");

                    mem.setText(str_old+"="+String.valueOf(FP(number[0])));

                }

2.下週計劃:藍牙


發佈了54 篇原創文章 · 獲贊 2 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章