基于Android实现计算器

最近发现我在CSDN里面分享的一些文件都被提高积分了,有的提高的有点夸张。所以以后我尽量把代码在博客里面贴全。

代码下载。

github地址:https://github.com/AtaoistPriest/Calculator

如果积分不够,复制以下代码也可以。当然欢迎积分下载。

这几天时间比较充裕,我用Android实现了一个计算器,以前也实现过,但那个版本功能简单,代码论乱,不易理解,关键是还有BUG。所以,我完善一下。实现计算器的难点主要是,输入算式时的排错和最后根据算术表达式求出数值。因为有括号,运算符优先级等问题,所以还是有点难度的。

计算器的界面如下:

基于Android实现计算器_第1张图片

好了,下面开始了。

界面布局文件:activity_main.xml



    
    
    
        

接下来是程序入口MainActivity.java

package com.example.ffy.orginal;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity implements View.OnClickListener {


    private TextView equationText,resultText;
    private Button buttons[] = new Button[26];

    private CheckInput checkInput;
    private CounterByEquation counterByEquation;

    //布局中所有按钮的ID
    private int buttonIds[] = new int[]{
            R.id.CE,R.id.BACKSPACE,R.id.Remainder,R.id.Involution,R.id.LBracket,R.id.RBracket,R.id.Factorial,
            R.id.Reciprocal,R.id.P,R.id.E, R.id.Divide,R.id.N7,R.id.N8,R.id.N9,R.id.Multiply,R.id.N4,
            R.id.N5,R.id.N6,R.id.Subtract,R.id.N1,R.id.N2,R.id.N3,R.id.Equal,R.id.Zero,R.id.Point, R.id.Add
    };
    //等式
    private String equation = "";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        init();  //初始化控件
    }
    /*
    * 点击计算器键盘
    *
    * */
    @Override
    public void onClick(View v) {

        int id = v.getId();
        Button button = (Button)findViewById(id);
        String text = button.getText().toString();
        switch (id){
            /*
            * 按数字按钮
            * */
            case R.id.N1:
            case R.id.N2:
            case R.id.N3:
            case R.id.N4:
            case R.id.N5:
            case R.id.N6:
            case R.id.N7:
            case R.id.N8:
            case R.id.N9:
            case R.id.Zero:
                checkInput.setEquation(equation);
                if(checkInput.checkNumberInput()){
                    equation = checkInput.getEquation();
                    equation += text;
                }
                break;
            /*
            * 点击 + - * /
            * */
            case R.id.Add:
            case R.id.Subtract:
            case R.id.Multiply:
            case R.id.Divide:
                checkInput.setEquation(equation);
                if(checkInput.checkOperationsInput()){
                    equation = checkInput.getEquation();
                    equation += text;
                }
                break;
             /*
             * 点击退格键
             *
             * */
            case R.id.BACKSPACE:
                checkInput.setEquation(equation);
                checkInput.backSpace();
                equation = checkInput.getEquation();
                break;
            /*
            * 点击 x^y
            * */
            case R.id.Involution:
                checkInput.setEquation(equation);
                if(checkInput.checkInvolutionInput())
                    equation+="^";
                break;
            /*
            * 倒数
            * */
            case R.id.Reciprocal:
                checkInput.setEquation(equation);
                if(checkInput.checkReciprocalInput())
                    equation+="^(-1)";
                break;
            /*
            * 左括号
            * */
            case R.id.LBracket:
                checkInput.setEquation(equation);
                if(checkInput.checkLBracketInput())
                    equation+="(";
                break;
            /*
            * 右括号
            * */
            case R.id.RBracket:
                checkInput.setEquation(equation);
                if(checkInput.checkRBracketInput())
                    equation+=')';
                break;
            /*
            * 取余
            * */
            case R.id.Remainder:
                checkInput.setEquation(equation);
                if(checkInput.checkRemainderInput())
                    equation+='%';
                break;
            /*
            * 求阶乘
            * */
            case R.id.Factorial:
                checkInput.setEquation(equation);
                if(checkInput.checkFactorialInput())
                    equation+='!';
                break;
            /*
            * 清空按钮
            * */
            case R.id.CE:
                equation = "";
                resultText.setText("");
                break;
            /*
            * 小数点按钮
            * */
            case R.id.Point:
                checkInput.setEquation(equation);
                if(checkInput.checkPointInput()){
                    equation = checkInput.getEquation();
                    equation+=text;
                }
                break;
            /*
            * 点击π
            * */
            case R.id.P:
                checkInput.setEquation(equation);
                if (checkInput.checkSpecialSymbolBack()){
                    equation+="π";
                }
                break;
            /*
            * 点击e
            * */
            case R.id.E:
                checkInput.setEquation(equation);
                if (checkInput.checkSpecialSymbolBack()){
                    equation+="e";
                }
                break;
            case R.id.Equal:
                resultText.setText(new CounterByEquation(equation).solveEquation());
                break;

        }
        equationText.setText(equation);
    }
    /*
    * init()初始化绑定所有的控件,并添加事件
    * */
    void init(){

        int length = buttons.length;
        for(int i=0;i

接下来是输入排错的功能,CheckInput.java.主要是加各种约束。

package com.example.ffy.orginal;

public class CheckInput {

    private String equation;


    public void setEquation(String equation){
        this.equation = equation;
    }

    public String getEquation(){
        return equation;
    }

    /*
     * 检查特殊符号输入问题,π或e,类似1e,2e,3e这样的按照出错处理
     * */
    boolean checkSpecialSymbolBack(){

        int length = equation.length();
        if(length==0) return true;
        char perChar = equation.charAt(length-1); //获取前一位字符
        if(perChar=='+'||perChar=='-'||perChar=='*'||perChar=='/') return true;
        return false;
    }



    /*
     *  检查输入数字
     * */
    boolean checkNumberInput(){
        int length = equation.length();
        if(length==0) return true;
        char perChar = equation.charAt(length-1);
        //避免出现  π1,e1,)1现象
        if(perChar=='π'||perChar=='e'||perChar==')'||perChar=='!') return false;
        //避免出现01,+001,2^00002等现象
        if(length==1&&perChar=='0') equation = "";
        if(length>1){
            char perPerChar = equation.charAt(length-2);
            if((perPerChar=='+'||perPerChar=='-'||perPerChar=='*'||perPerChar=='/'||perPerChar=='^')&&perChar=='0'){
                equation = equation.substring(0,length-1);
            }
        }
        return true;
    }


    /*
     *小数点输入检查
     * */
    boolean checkPointInput(){

        int length = equation.length();
        //自动补0
        if(length==0) equation+="0";
        char perChar = equation.charAt(length-1);
        //自动补0
        if(perChar=='+'||perChar=='-'||perChar=='*'||perChar=='/'||perChar=='%') equation+="0";
        if(perChar=='π'||perChar=='e'||perChar==')'||perChar=='('||perChar=='^'||perChar=='!') return false;
        int pointNum = 0;
        for(int i = length-1;i>=0;i--){
            char checkChar = equation.charAt(i);
            if(checkChar=='.') pointNum++;
            if(checkChar=='^') return false;
            if(checkChar=='+'||checkChar=='-'||checkChar=='*'||checkChar=='/'||checkChar=='%') break;
        }
        if(pointNum>0) return false;
        return true;
    }
    /*
     * 输入+ - * / 时进行检查,在他们的前面不能有 .和%
     * */
    boolean checkOperationsInput(){
        int length = equation.length();
        if(length==0) return false;
        char perChar = equation.charAt(length-1);
        if(perChar=='%'||perChar=='.'||perChar=='^'||perChar=='!'||perChar=='(') return false;
        //替换
        if(perChar=='+'||perChar=='-'||perChar=='*'||perChar=='/')
            equation = equation.substring(0,length-1);
        return true;
    }
    /*
     * 退格处理
     * */
    void backSpace(){

        int length = equation.length();
        if(length==0) return;
        char charPer = equation.charAt(length-1);
        equation = equation.substring(0,length-1);
    }
    /*
     * 检查 x^y
     * */
    boolean checkInvolutionInput(){

        int length = equation.length();
        if(length==0) return false;
        char perChar = equation.charAt(length-1);
        if(perChar!='1'&&perChar!='2'&&perChar!='3'&&perChar!='4'&&perChar!='5'&&perChar!='6'&&perChar!='7'
                &&perChar!='8'&&perChar!='9'&&perChar!=')'&&perChar!='e'&&perChar!='π'&&perChar!='0') return false;
        //一个式子里只能有 ^
        int iNum = 0;
        for(int i = length-1;i>0;i--){
            char iChar = equation.charAt(i);
            if(iChar=='^') iNum++;
            if (iChar=='+'||iChar=='-'||iChar=='*'||iChar=='/'||iChar=='%') break;
        }
        if(iNum>0) return false;
        return true;
    }
    /*
     * 倒数
     * */
    boolean checkReciprocalInput(){
        int length = equation.length();
        if(length==0) return false;
        char perChar = equation.charAt(length-1);
        if(perChar!='1'&&perChar!='2'&&perChar!='3'&&perChar!='4'&&perChar!='5'&&perChar!='6'&&perChar!='7'
                &&perChar!='8'&&perChar!='9'&&perChar!=')'&&perChar!='0') return false;
        //单独一个0不能求倒数
        int iNum = 0;
        for(int i = length-1;i>=0;i--){
            char iChar = equation.charAt(i);
            iNum++;
            if (iChar=='+'||iChar=='-'||iChar=='*'||iChar=='/'||iChar=='%') break;
        }
        if(iNum==1&&perChar=='0') return false;
        return true;
    }
    /*
     * 输入左括号
     * */
    boolean checkLBracketInput(){
        int length = equation.length();
        if(length==0) return true;
        char perChar = equation.charAt(length-1);
        if(perChar=='+'||perChar=='-'||perChar=='*'||perChar=='/'||perChar=='%'||perChar=='^'||perChar=='(') return true;
        return false;
    }
    /*
     * 输入右括号
     * */
    boolean checkRBracketInput(){
        int length = equation.length();
        if(length==0) return false;
        char perChar = equation.charAt(length-1);
        //左右符号要匹配
        int lNum = 0,rNum = 0;
        for(int i = length-1;i>=0;i--){
            char checkChar = equation.charAt(i);
            if(checkChar=='(') lNum++;
            if(checkChar==')') rNum++;
            if(lNum-rNum==1) break;
        }
        if((lNum-rNum==1)&&(perChar=='1'||perChar=='2'||perChar=='3'||perChar=='4'||perChar=='5'||perChar=='6'||perChar=='7'
                ||perChar=='8'||perChar=='9'||perChar=='0'||perChar==')')) return true;
        return false;
    }
    /*
     *  取余
     * */
    boolean checkRemainderInput(){
        int length = equation.length();
        if(length==0) return false;
        char perChar = equation.charAt(length-1);
        if(perChar=='1'||perChar=='2'||perChar=='3'||perChar=='4'||perChar=='5'||perChar=='6'||perChar=='7'
                ||perChar=='8'||perChar=='9'||perChar==')') return true;

        return false;
    }
    /*
     * 求阶乘
     * */
    boolean checkFactorialInput(){
        int length = equation.length();
        if(length==0) return false;
        char perChar = equation.charAt(length-1);
        if(perChar=='!'||perChar=='%'||perChar=='^'||perChar=='('||perChar=='+'
                ||perChar=='-'||perChar=='*'||perChar=='/') return false;
        //小数点阶乘不可以存在
        for(int i=length-1;i>=0;i--){
            char checkChar = equation.charAt(i);
            if(checkChar=='.') return false;
            if(checkChar=='+'||checkChar=='-'||checkChar=='*'||checkChar=='/') break;
        }
        return true;
    }
}

最后是根据算术表达式求出最终结果。主要思路是,先转换为后缀表达式,再根据后缀表达式求值。CounterByEquation.java

package com.example.ffy.orginal;

import android.util.Log;

import java.util.Stack;
import java.util.Queue;


public class CounterByEquation {

    private String equation;

    private Stack stack;  //存储符号
    private String []queue = new String[50];  //接受中缀表达式
    private int count=0;


    public CounterByEquation(String equation){
        this.equation = equation;
    }

    /*
    *           (  )   * - / +  ^  !  x^(-1)  %  e  π   3.11 5
    *
    *           ((3^5)+5^(-1)+((6%4)+e)*6)*2
    *           3^5 5^-1 + 6%4 e + 6 * +
    * */
    String solveEquation(){

        int length = equation.length();

        /*
        * 由中缀表达式求后缀表达式
        * */
        stack = new Stack<>();

        for(int i=0;i0){
                    sum *= (num--);
                }
                queue[i] = sum+"";
                continue;
            }
            if(member.equals("π")) {
                queue[i] = "3.1415926";
                continue;
            }
            if(member.equals("e")) {
                queue[i] = "2.71828183";
                continue;
            }

            if(member.equals("+")||member.equals("-")||member.equals("*")||member.equals("/")||member.equals("%")||member.equals("^")){
                double first = Double.parseDouble(queue[i-2]);
                double second = 0;
                if(!queue[i-1].equals("-"))
                    second = Double.parseDouble(queue[i-1]);
                if (member.equals("+")) first += second;
                if (member.equals("-")){
                    //处理  x^(-1)的情况
                    if(queue[i+1]!=null&&queue[i+1].equals("^")){
                        first = 1 / first;
                        //为了不影响接下来的运算,在数组去除^
                        for(int j = i+1;j0;j--){
                        sum*=first;
                    }
                    first = sum;
                }
                queue[i-2] = first+"";
                //前移
                for(int j = i-1;j

 

你可能感兴趣的:(基于Android实现计算器)