简易计算器的实现

计算器可实现±*/负号以及括号的运算

主要用到中缀转后缀,可以先了解一下中缀转后缀的思想,再进行计算器的实现

计算器的布局如图:

在这里插入图片描述
布局使用的是LinerLayout的嵌套,可以模仿自己手机的计算器布局。

设置输入为一行,可进行字体自动缩小,不过没有光标的移动,未设置最多输入位数

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/edit_text"
        app:autoSizeMaxTextSize = "80sp"
        app:autoSizeMinTextSize = "20sp"
        app:autoSizeStepGranularity= "3sp"
        app:autoSizeTextType = "uniform"
        android:layout_width="match_parent"
        android:maxLines="1"
        android:layout_height="200dp"
        android:background="#FFFFFF"
        android:gravity="right|bottom"
        android:editable="false"
        />
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        >

        <Button
            android:id="@+id/button_c"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="c"
            android:textColor="#63B8FF"
            android:textSize="30sp"
            android:background="@drawable/ev_shape"
            />

        <Button
            android:id="@+id/button_div"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="÷"
            android:textColor="#63B8FF"
            android:textSize="30sp"
            android:background="@drawable/ev_shape"
            />

        <Button
            android:id="@+id/button_mul"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="×"
            android:textColor="#63B8FF"
            android:textSize="30sp"
            android:background="@drawable/ev_shape"
            />

        <Button
            android:id="@+id/button_delete"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="d"
            android:textColor="#63B8FF"
            android:textSize="30sp"
            android:background="@drawable/ev_shape"
            />

    </LinearLayout>

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        >
        <Button
            android:id="@+id/button_7"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="7"
            android:textSize="30sp"
            android:background="@drawable/ev_shape1"
            />
        <Button
            android:id="@+id/button_8"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="8"
            android:textAllCaps="false"
            android:textSize="30sp"
            android:background="@drawable/ev_shape1"
            />

        <Button
            android:id="@+id/button_9"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="9"
            android:textAllCaps="false"
            android:textSize="30sp"
            android:background="@drawable/ev_shape1"
            />

        <Button
            android:id="@+id/button_sub"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="-"
            android:textColor="#63B8FF"
            android:textSize="30sp"
            android:background="@drawable/ev_shape"
            />

    </LinearLayout>

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        >
        <Button
            android:id="@+id/button_4"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="4"
            android:textSize="30sp"
            android:background="@drawable/ev_shape1"
            />
        <Button
            android:id="@+id/button_5"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="5"
            android:textAllCaps="false"
            android:textSize="30sp"

            android:background="@drawable/ev_shape1"
            />

        <Button
            android:id="@+id/button_6"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="6"
            android:textAllCaps="false"
            android:textSize="30sp"
            android:background="@drawable/ev_shape1"
            />

        <Button
            android:id="@+id/button_sum"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="+"
            android:textColor="#63B8FF"
            android:textSize="30sp"
            android:background="@drawable/ev_shape"
            />
    </LinearLayout>

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        >

        <Button
            android:id="@+id/button_1"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="1"
            android:textSize="30sp"
            android:background="@drawable/ev_shape1"/>

        <Button
            android:id="@+id/button_2"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@drawable/ev_shape1"
            android:gravity="center"
            android:text="2"
            android:textAllCaps="false"
            android:textSize="30sp" />

        <Button
            android:id="@+id/button_3"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@drawable/ev_shape1"
            android:gravity="center"
            android:text="3"
            android:textAllCaps="false"
            android:textSize="30sp" />


        <Button
            android:id="@+id/button_point"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@drawable/ev_shape"
            android:gravity="center"
            android:text="."
            android:textColor="#63B8FF"
            android:textAllCaps="false"
            android:textSize="30sp" />

    </LinearLayout>

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        >

        <Button
            android:id="@+id/button_0"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@drawable/ev_shape1"
            android:gravity="center"
            android:text="0"
            android:textSize="30sp" />

        <Button
            android:id="@+id/left"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@drawable/ev_shape1"
            android:gravity="center"
            android:text="("
            android:textSize="30sp" />

        <Button
            android:id="@+id/right"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text=")"
            android:textSize="30sp"
            android:background="@drawable/ev_shape1"//自定义布局
            />

        <Button
            android:id="@+id/equ"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="#4F94CD"
            android:text="="
            android:gravity="center"
            android:textColor="#63B8FF"
            android:textSize="30sp" />
    </LinearLayout>

</LinearLayout>

里面涉及的自定义布局在project中的app->src->main->rec->drawable中
ev_shape

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">

    <solid
        android:color="#F0F0F0"/>//内部填充颜色

    <stroke android:width="1dip"
        android:color="#F5F5F5" />//轮廓颜色
</shape>

ev_shape1

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">

    <solid
        android:color="#FFFFFF"/>

    <stroke android:width="1dip"
        android:color="#F5F5F5" />
</shape>

主活动中:

private TextView editText;
    private int flag = 1;
    private  String result;
    private boolean flag1 = false;
    private StringBuilder add = new StringBuilder();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ActionBar actionBar = getSupportActionBar();
        if(actionBar != null) {
            actionBar.hide();
        }
//获取布局中定义的元素
        Button button0 = (Button) findViewById(R.id.button_0);
        Button button1 = (Button) findViewById(R.id.button_1);
        Button button2 = (Button) findViewById(R.id.button_2);
        Button button3 = (Button) findViewById(R.id.button_3);
        Button button4 = (Button) findViewById(R.id.button_4);
        Button button5 = (Button) findViewById(R.id.button_5);
        Button button6 = (Button) findViewById(R.id.button_6);
        Button button7 = (Button) findViewById(R.id.button_7);
        Button button8 = (Button) findViewById(R.id.button_8);
        Button button9 = (Button) findViewById(R.id.button_9);
        Button buttonDele = (Button) findViewById(R.id.button_delete);
        Button buttonDiv = (Button) findViewById(R.id.button_div);
        Button buttonEqu = (Button) findViewById(R.id.equ);
        Button buttonC = (Button) findViewById(R.id.button_c);
        Button buttonMul = (Button) findViewById(R.id.button_mul);
        Button buttonSum = (Button) findViewById(R.id.button_sum);
        Button buttonSub = (Button) findViewById(R.id.button_sub);
        Button buttonPoint = (Button) findViewById(R.id.button_point);
        Button left = (Button) findViewById(R.id.left);
        Button right = (Button) findViewById(R.id.right);
        editText = (TextView) findViewById(R.id.edit_text
        //为按钮注册监听器
        buttonPoint.setOnClickListener(this);
        button0.setOnClickListener(this);
        button1.setOnClickListener(this);
        button2.setOnClickListener(this);
        button3.setOnClickListener(this);
        button4.setOnClickListener(this);
        button5.setOnClickListener(this);
        button6.setOnClickListener(this);
        button7.setOnClickListener(this);
        button8.setOnClickListener(this);
        button9.setOnClickListener(this);
        left.setOnClickListener(this);
        right.setOnClickListener(this);
        buttonDiv.setOnClickListener(this);
        buttonDele.setOnClickListener(this);
        buttonC.setOnClickListener(this);
        buttonMul.setOnClickListener(this);
        buttonSum.setOnClickListener(this);
        buttonSub.setOnClickListener(this);
        buttonEqu.setOnClickListener(this);

    }
    @Override
    public void onClick(View view) {
        int last = 0;
        if(add.length() != 0) {
            last = add.codePointAt(add.length()-1);
        }
        //不能无限的输入0
        if(add.length() == 1 && add.charAt(0) == '0') {
            add.deleteCharAt(0);
        }
        switch (view.getId()) {
            case R.id.button_0:
                if(flag1) {//第一次计算出结果,当点击数字时,进行新的运算
                    add.delete(0,add.length());
                    flag1 = false;
                    add = add.append("0");
                }else if(flag1() == ')') {
                    add = add.append("*0");//将(表达式)0转成为(表达式)*0进行计算,下面类似
                }else{
                    add = add.append("0");
                }
                editText.setText(add);
                break;
            case R.id.button_1:

                if(flag1) {
                    add.delete(0,add.length());
                    flag1 = false;
                    add = add.append("1");
                }else if(flag1() == ')') {
                    add = add.append("*1");
                }else{
                    add = add.append("1");
                }

                editText.setText(add);
                break;
            case R.id.button_2:
                if(flag1) {//
                    add.delete(0,add.length());
                    flag1 = false;
                    add = add.append("2");
                }else if(flag1() == ')') {
                    add = add.append("*2");
                }else{
                    add = add.append("2");

                }

                editText.setText(add);
                break;
            case R.id.button_3:
                if(flag1) {
                    add.delete(0,add.length());
                    flag1 = false;
                    add = add.append("3");
                }else if(flag1() == ')') {
                    add = add.append("*3");
                }else{
                    add = add.append("3");
                }

                editText.setText(add);
                break;
            case R.id.button_4:
                if(flag1) {
                    add.delete(0,add.length());
                    flag1 = false;
                    add = add.append("4");
                }else if(flag1() == ')') {
                    add = add.append("*4");
                }else{

                    add = add.append("4");
                }

                editText.setText(add);
                break;
            case R.id.button_5:
                if(flag1) {
                    add.delete(0,add.length());
                    flag1 = false;
                    add = add.append("5");
                }else if(flag1() == ')') {
                    add = add.append("*5");
                }else{
                    add = add.append("5");
                }

                editText.setText(add);
                break;
            case R.id.button_6:
                if(flag1) {
                    add.delete(0,add.length());
                    flag1 = false;
                    add = add.append("6");
                }else if(flag1() == ')') {
                    add = add.append("*6");
                }else{
                    add = add.append("6");
                }

                editText.setText(add);
                break;
            case R.id.button_7:
                if(flag1) {
                    add.delete(0,add.length());
                    flag1 = false;
                    add = add.append("7");
                }else if(flag1() == ')') {
                    add = add.append("*7");
                }else{
                    add = add.append("7");
                }

                editText.setText(add);
                break;
            case R.id.button_8:
                if(flag1) {
                    add.delete(0,add.length());
                    flag1 = false;
                    add = add.append("8");
                }else if(flag1() == ')') {
                    add = add.append("*8");
                }else{

                    add = add.append("8");
                }

                editText.setText(add);
                break;

            case R.id.button_9:
                if(flag1) {
                    add.delete(0,add.length());
                    flag1 = false;
                    add = add.append("9");
                }else if(flag1() == ')') {
                    add = add.append("*9");
                }else{
                    add = add.append("9");
                }

                editText.setText(add);
                break;

            case R.id.button_sub:
                if(flag1) {//当第一次计算出结果,点击运算符则保存第一次计算的结果。
                    flag1 = false;
                }
                if(Character.isDigit(flag1()) || flag1() == ')' || flag1() == '('|| flag1() == '+' || flag1() == '*' || flag1() == '/' || flag1() == '.' || add.length() == 0){
                    add = add.append("-");
                    flag = 1;
                    editText.setText(add);
                }
                break;
            case R.id.left:
                if(flag1) {
                    add.delete(0, add.length());
                    flag1 = false;
                    add = add.append("(");

                    editText.setText(add);
                }else if((add.length() >1 && last <= '0' && last >= '9' || last != '(' || last == '(' )&& flag1() == '-'){//(前面为-时转化为-1*(计算
                    add.insert(add.length() - 1,"-1*(");
                    add.delete(add.length() - 1,add.length());
                    editText.setText(add);
                } else if(Character.isDigit(flag1())){//当(前面为数字,则转化为 数字*(
                    add = add.append("*(");
                    editText.setText(add);
            }else if( last <= '0' && last >= '9' || last != '(' || last == '(') {
                    add = add.append("(");
                    editText.setText(add);
                }
                break;

            case R.id.right:
                if((last >= '0' && last <= '9' || last == ')') && flag2() == 1) {
                    add = add.append(")");

                    editText.setText(add);
                }
                break;
            case R.id.button_div:
                if(flag1) {
                    flag1 = false;
                }
                if (Character.isDigit(flag1()) || flag1() == ')' || flag1() == '.') {
                    add = add.append("/");
                    flag = 1;
                }
                if(add.length() == 0) {
                    add.append("0/");
                }
                editText.setText(add);
                break;

            case R.id.button_sum:
                if(flag1) {
                    flag1 = false;
                }
                if(Character.isDigit(flag1()) || flag1() == ')' || flag1() == '.'){
                    add = add.append("+");
                    flag = 1;
                    editText.setText(add);
            }
                if(add.length() == 0) {
                    add.append("0+");
                    editText.setText(add);
                }
                break;
            case R.id.button_mul:
                if(flag1) {
                    flag1 = false;
                }
                if (Character.isDigit(flag1()) || flag1() == ')' || flag1() == '.') {
                    add = add.append("*");
                    flag = 1;
                }
                if(add.length() == 0) {
                    add.append("0*");
                }
                editText.setText(add);
                break;
            case R.id.button_delete:
                if (add.length() != 0) {
                    flag = 1;
                    add.delete(add.length() - 1, add.length());
                    editText.setText(add);
                }
                break;
            case R.id.button_point:
            //下面一系列判断,限制小数点的输入
                char ch;
                if(add.length() == 0) {
                    ch = '$';
                }
                else{
                    ch = add.charAt(add.length() - 1);
                }
                if(flag1) {
                    add.delete(0,add.length());
                    flag1 = false;
                }
                if(ch == '+' || ch == '-' || ch == '*' || ch == '/' || add.length() == 0) {
                    add.append("0.");
                    flag = 0;
                    editText.setText(add);
                }else if(ch != '.' && flag == 1 && flag1() != ')') {
                    add = add.append(".");
                    flag = 0;
                    editText.setText(add);
                }else if(ch == ')') {
                    add.append("*0.");
                    editText.setText(add);
                }
                break;
            case R.id.button_c:
                flag = 1;
                add.delete(0,add.length());
                editText.setText(add);
                break;
            case R.id.equ:
                if(add.length() > 1) {
//自动进行括号匹配
                    try{
                        while(flag2() != 0) {
                            add.append(")");
                        }
                        Result r = new Result();
                        String a = r.getString(add);
                        result = r.getResult(a);
                        editText.setText(result);
                        add = add.delete(0,add.length());
                        if(Character.isDigit(result.charAt(0)) || Character.isDigit(result.charAt(1))) {
                            flag1 = true;
                            add = add.append(result);
                        }
                    }catch (Exception e) {
                        result = "错误";
                        editText.setText(result);
                    }
                }
                break;
            default:
                break;
        }
    }

    public char flag1() {//获取当前显示的最新的字符
        char ch;
        if(add.length() >= 1) {
             ch = add.charAt(add.length() - 1);
        }else {
             ch = '&';
        }
        return ch;
    }


//对左右括号进行计数,可进行括号的匹配
    public int flag2() {
        int a = 0;
        int b = 0;
        for(int i = 0; i < add.length(); i++) {
            if(add.charAt(i) == '(') {
                a++;
            }
            if(add.charAt(i) == ')') {
                b++;
            }
        }
        if(a == b)
            return 0;
        if(a > b)
            return 1;
        return 2;
    }
}

中缀转后缀及计算


class Result {
    public String getString(StringBuilder add) {
        HashMap<Character,Integer> hm = new HashMap<>();
        //判断优先级
        hm.put('(',0);
        hm.put('+',1);
        hm.put('-',1);
        hm.put('*',2);
        hm.put('/',2);
        ArrayList<String> al = new ArrayList<>();
        ArrayList<Character> stack = new ArrayList<>();
        char[] arr = add.substring(0, add.length()).toCharArray();
        String show = "+-*/()";
        char ch;
        int len = 0;
//下面都是中缀转后缀的实现,当栈定的运算符优先级大于即将入栈的运算符,
//则栈内的运算符全部出栈
        for (int i = 0; i < arr.length; i++) {
            ch = arr[i];
            if(ch == '-' && i == 0 ) {
                al.add("0");
            }
            if (Character.isDigit(ch)) {
                ++ len;
            } else if (ch == '.') {
                ++ len;
            }
            else if(ch == '-' && i != 0 && show.indexOf(arr[i - 1])!= -1 && arr[i - 1] != ')') {
                    ++ len;
            }else if (show.indexOf(ch) != -1) {
                if (len > 0) {
                    al.add(String.valueOf(Arrays.copyOfRange(arr, i - len, i)));
                    len = 0;
                }
                if(ch == '(') {
                    stack.add(ch);
                    continue;
                }
                if(!stack.isEmpty()) {
                    int size = stack.size() - 1;
                    boolean flag = false;
                    while (size >= 0 && ch == ')' && stack.get(size) != '(') {
                        al.add(String.valueOf(stack.remove(size)));//获取数字
                        size --;//保证一直指向栈顶元素
                        flag = true;
                    }
                    if(ch == ')' && stack.get(size) == '(') {
                        flag = true;
                    }
                    while(size >= 0 && !flag && hm.get(stack.get(size)) >= hm.get(ch)) {
                        al.add(String.valueOf(stack.remove(size)));
                        size --;
                    }
                }
                if(ch != ')') {
                    stack.add(ch);
                }else{
                    stack.remove(stack.size() - 1);//'('出栈
                }
            }
            if(i == arr.length - 1) {
                if(len > 0) {
                    al.add(String.valueOf(Arrays.copyOfRange(arr, i - len+1, i+1)));
                }
                int size = stack.size() - 1;
                while(size >= 0) {
                    al.add(String.valueOf(stack.remove(size)));
                    size --;

                }
            }
        }
        String a = al.toString();
        return a.substring(1,a.length() - 1);
    }

//后缀表达式的计算
    public String getResult(String string) {
        String[] arr = string.split(",");
        ArrayList<String> list = new ArrayList<>();
       for(int i = 0;i < arr.length; i++) {
            int size = list.size();
            switch (arr[i]) {
                case " -" :
                    BigDecimal a = new BigDecimal(list.remove(size - 2)).subtract(new BigDecimal(list.remove(size - 2)));
                    list.add(a.toString());
                    break;
                case " +" :
                    BigDecimal b = new BigDecimal(list.remove(size - 2)).add(new BigDecimal(list.remove(size - 2)));
                    list.add(b.toString());
                    break;
                case " *" :
                    BigDecimal c = new BigDecimal(list.remove(size - 2)).multiply(new BigDecimal(list.remove(size - 2)));
                    list.add(c.toString());
                    break;
                case " /" :
                    BigDecimal d = new BigDecimal(list.remove(size - 2));
                    BigDecimal d1 = new BigDecimal(list.remove(size - 2));
                    list.add(String.valueOf(d.divide(d1,9, BigDecimal.ROUND_HALF_UP).doubleValue()));
                    break;
                    default:
                    list.add(arr[i].trim());
                    break;
            }
        }
        String line;
        //数字/0位Infinity,报错
        if(list.size() == 1 && list.get(0) != "Infinity") {
           line = list.get(0);
        }else{
            line = "错误";
        }
        return line;
    }
}

可以改计算器app的图标

换的图片放在 Project下的app->src->main->res->drawable
打开 AndroidMainfest.xml

android:allowBackup="true"
android:icon="@drawable/my"//要换的图标
android:label="suager"//app的名字
android:supportsRtl="true"
android:theme="@style/AppTheme">
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值