安卓计算器实现

  最近刚开始接触安卓编程,移动应用开发可以使用Java或者Kotlin语言,因为没有学过Kotlin,所以计算器的实现采用Java语言。要实现计算器的功能就需要将我们输入的算式(中缀式)转化为后缀式。这样方便计算。关于如何将中缀式转化为后缀式,大家可以参考其他文章。

Java代码

package com.example.caculate;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import org.w3c.dom.Text;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private TextView textView;    // 文本框
    StringBuilder content = new StringBuilder();   //获取TextView里的内容
    StringBuilder stringBuilder = new StringBuilder();

    Stack<String> sta = new Stack<String>();        //符号栈
    List<String> stack = new ArrayList<String>();   //后缀式的集合
    Map<String, Integer> priority = new HashMap<String, Integer>();  //设置符号优先级

    //数字0-9
    private Button number_zero;
    private Button number_one;
    private Button number_two;
    private Button number_three;
    private Button number_four;
    private Button number_five;
    private Button number_six;
    private Button number_seven;
    private Button number_eight;
    private Button number_nine;

    //操作符
    private Button operator_mod;
    private Button operator_add;
    private Button operator_back;     //退一格
    private Button operator_point;
    private Button operator_equal;
    private Button operator_clear;    //清除
    private Button operator_remove;
    private Button operator_subtract;
    private Button operator_multiply;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //设置符号优先级
        priority.put("+", 1);
        priority.put("-", 1);
        priority.put("*", 0);
        priority.put("/", 0);
        priority.put("%", 0);

        //TextView
        textView = findViewById(R.id.textView);

        //数字键
        number_zero = findViewById(R.id.number_zero);
        number_zero.setOnClickListener(this);
        number_one = findViewById(R.id.number_one);
        number_one.setOnClickListener(this);
        number_two = findViewById(R.id.number_two);
        number_two.setOnClickListener(this);
        number_three = findViewById(R.id.number_three);
        number_three.setOnClickListener(this);
        number_four = findViewById(R.id.number_four);
        number_four.setOnClickListener(this);
        number_five = findViewById(R.id.number_five);
        number_five.setOnClickListener(this);
        number_six = findViewById(R.id.number_six);
        number_six.setOnClickListener(this);
        number_seven = findViewById(R.id.number_seven);
        number_seven.setOnClickListener(this);
        number_eight = findViewById(R.id.number_eight);
        number_eight.setOnClickListener(this);
        number_nine = findViewById(R.id.number_nine);
        number_nine.setOnClickListener(this);

        //算数符号
        operator_mod =findViewById(R.id.operator_mod);
        operator_mod.setOnClickListener(this);
        operator_add =findViewById(R.id.operator_add);
        operator_add.setOnClickListener(this);
        operator_back = findViewById(R.id.operator_back);
        operator_back.setOnClickListener(this);
        operator_equal =findViewById(R.id.operator_equal);
        operator_equal.setOnClickListener(this);
        operator_clear =findViewById(R.id.operator_clear);
        operator_clear.setOnClickListener(this);
        operator_remove =findViewById(R.id.operator_remove);
        operator_remove.setOnClickListener(this);
        operator_subtract =findViewById(R.id.operator_subtract);
        operator_subtract.setOnClickListener(this);
        operator_multiply =findViewById(R.id.operator_multiply);
        operator_multiply.setOnClickListener(this);
        operator_point = findViewById(R.id.operator_point);
        operator_point.setOnClickListener(this);
    }

    //重写按钮点击的click方法
    @Override
    public void onClick(View v) {
        switch(v.getId()){
            case R.id.number_zero:
                content.append("0");
                textView.setText(content);
                break;
            case R.id.number_one:
                content.append("1");
                textView.setText(content);
                break;
            case R.id.number_two:
                content.append("2");
                textView.setText(content);
                break;
            case R.id.number_three:
                content.append("3");
                textView.setText(content);
                break;
            case R.id.number_four:
                content.append("4");
                textView.setText(content);
                break;
            case R.id.number_five:
                content.append("5");
                textView.setText(content);
                break;
            case R.id.number_six:
                content.append("6");
                textView.setText(content);
                break;
            case R.id.number_seven:
                content.append("7");
                textView.setText(content);
                break;
            case R.id.number_eight:
                content.append("8");
                textView.setText(content);
                break;
            case R.id.number_nine:
                content.append("9");
                textView.setText(content);
                break;
            case R.id.operator_add:
                inpu("+");
                break;
            case R.id.operator_subtract:
                inpu("-");
                break;
            case R.id.operator_multiply:
                inpu("*");
                break;
            case R.id.operator_remove:
                inpu("/");
                break;
            case R.id.operator_mod:
                inpu("%");
                break;
            case R.id.operator_point:
                inpu(".");
                break;
            case R.id.operator_back:           //  输入的内容后退一格
                if (content.length()!=0){
                    content.deleteCharAt(content.length()-1); //删除最后一个字符
                    textView.setText(content);
                }
                break;
            case R.id.operator_clear:
                textView.setText(content.delete(0,content.length()));
                break;
            case R.id.operator_equal:
                if (stack.size()!=0||sta.size()!=0){
                    sta.clear();
                    stack.clear();
                }
                String str ;
                String first;
                String primary = content.toString();
                if(primary.length()==1){ // 当用户输入的字符串仅为一个运算符或者没有注入
                    if (!Character.isDigit(primary.charAt(0))){
                        textView.setText("");
                        break;
                    }
                    str = primary;
                } else if(primary.length()==0){
                    str = primary;
                    break;
                } else{
                    first = String.valueOf(primary.charAt(0));
                    if(first.equals("+")||first.equals("*")||first.equals("/")||first.equals("%")||first.equals(".")){
                        str = primary.substring(1,primary.length());
                        if (!Character.isDigit(primary.charAt(primary.length()-1))){ //判断字符串的结尾是否为数字
                            str = str.substring(0,str.length()-1);
                        }
                    } else{
                        if (!Character.isDigit(primary.charAt(primary.length()-1))){
                            str = primary.substring(0,primary.length()-1);
                        }else{
                            str = primary;
                        }
                    }
                }
                //将中缀表达式转换为后缀表达式
                for (int i = 0; i < str.length(); i++) {
                    if (Character.isDigit(str.charAt(i))||String.valueOf(str.charAt(i)).equals(".")) {
                        stringBuilder.append(str.charAt(i));
                        if (i == str.length() - 1) {
                            stack.add(stringBuilder.toString());
                            stringBuilder.delete(0, stringBuilder.length());
                        }
                    } else {
                       stack.add(stringBuilder.toString());
                        stringBuilder.delete(0, stringBuilder.length());
                        if (!sta.empty()) {
                            for (int k = 0; k < sta.size(); k++) {
                                if (priority.get(String.valueOf(str.charAt(i))) >= priority.get(sta.peek())) {
                                    stack.add(sta.pop());
                                    if (sta.isEmpty()) {
                                        sta.push(String.valueOf(str.charAt(i)));
                                        break;
                                    } else {
                                        k--;
                                    }
                                } else {
                                    sta.push(String.valueOf(str.charAt(i)));
                                    break;
                                }
                            }
                        } else {
                            sta.push(String.valueOf(str.charAt(i)));
                        }
                    }
                    if (i == str.length() - 1) {
                        while (!sta.isEmpty()) {
                            stack.add(sta.pop());
                        }
                    }
                }

                for (int p=0; p<stack.size(); p++){
                    if (stack.get(p).equals("")){
                        stack.remove(p);
                    }
                }
                for (int i = 0; i < stack.size(); i++) {
                    if (stack.get(i).equals("+") || stack.get(i).equals("-") || stack.get(i).equals("*")|| stack.get(i).equals("/") || stack.get(i).equals("%")) {
                        switch (stack.get(i)) {
                            case "*":
                                String sum = String.valueOf(Double.valueOf(stack.get(i - 2))* Double.valueOf(stack.get(i - 1)).intValue());
                                simplify(stack, i, sum);
                                i = 0;
                                break;
                            case "/":
                                if(Integer.parseInt(stack.get(i - 1))==0) {    //被除数为零
                                    stack.clear();
                                    stack.add("格式错误");
                                    break;
                                }
                                String a = String.valueOf(Double.valueOf(stack.get(i - 2))/ Double.valueOf(stack.get(i - 1)));
                                simplify(stack, i, a);
                                i = 0;
                                break;
                            case "+":
                                String b = String.valueOf(Double.valueOf(stack.get(i - 2)) + Double.valueOf(stack.get(i - 1)));
                                simplify(stack, i, b);
                                i = 0;
                                break;
                            case "-":
                                if(i==1) {  //负号前面只有一个数
                                    String minus = "-"+ stack.get(i - 1);
                                    stack.remove(stack.get(i));
                                    stack.remove(stack.get(i-1));
                                    stack.add(0, minus);
                                    break;
                                }
                                String c = String.valueOf(Double.valueOf(stack.get(i - 2)) - Double.valueOf(stack.get(i - 1)));
                                simplify(stack, i, c);
                                i = 0;
                                break;
                            case "%":
                                String d = String.valueOf(Double.valueOf(stack.get(i - 2)).intValue() % Double.valueOf(stack.get(i - 1)).intValue());
                                simplify(stack, i, d);
                                i = 0;
                                break;
                        }
                    }
                }
                content.delete(0,content.length());
                content.append(stack.get(0));
                textView.setText(content);
                break;
        }
    }

    //判断最后一个字符是否为算数运算符,并且算术运算符前不能为point :点;
   public boolean check(String string){
        if (string.equals("+")||string.equals("-")||string.equals("*")||string.equals("/")||string.equals("%")||string.equals(".")){
            return true;
        }else {
            return false;
        }
    }

    //计算后缀式的时候合并算数符号在内的所占的位置
    public String simplify(List<String> list, int index, String para) {
        list.remove(list.get(index));
        list.remove(list.get(index - 1));
        list.remove(list.get(index - 2));
        list.add(index - 2, para);
        return " ";
    }

    //数字后面只能加一个算数符号或者点
    public View inpu(String operator){
        if (content.length()==0){
            content.append(operator);
            textView.setText(content);
        }else {
            if (check(String.valueOf(content.charAt(content.length() - 1)))) {
                content.replace(content.length() - 1, content.length(), operator);
                textView.setText(content);
            } else {
                content.append(operator);
                textView.setText(content);
            }
        }
        return  textView;
    }
}

布局文件

UI界面主要采用了约束布局与线性布局结合的方式,可以提高开发效率。计算器按钮采用网格式布局,更方便实现。

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        //将线性布局填充到整个界面
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        >

        <TextView
            android:id="@+id/textView"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"   //权重是1,TextView占屏幕的1/4
            android:gravity="center_vertical|end"
            android:text="应该没有BUG"
            android:textSize="50sp" />

        <GridLayout
            android:id="@+id/gridLayout"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="3" //权重是1,TextView占屏幕的3/4
            //创建一个5行4列的网格布局
            android:rowCount="5"
            android:columnCount="4"
            >


            <Button   
                android:id="@+id/operator_clear"
                android:layout_width="0dp"
                android:layout_height="0dp"
                android:layout_columnWeight="1"
                android:layout_rowWeight="1"
                android:text="C"
                android:textSize="50sp"/>

            <Button
                android:id="@+id/operator_back"
                android:layout_width="0dp"
                android:layout_height="0dp"
                android:layout_columnWeight="1"
                android:layout_rowWeight="1"
                android:text="De"
                android:textSize="50sp"/>

            <Button
                android:id="@+id/operator_mod"
                android:layout_width="0dp"
                android:layout_height="0dp"
                android:layout_columnWeight="1"
                android:layout_rowWeight="1"
                android:text="%"
                android:textSize="50sp"/>

            <Button
                android:id="@+id/operator_remove"
                android:layout_width="0dp"
                android:layout_height="0dp"
                android:layout_columnWeight="1"
                android:layout_rowWeight="1"
                android:text="÷"
                android:textSize="50sp"/>

            <Button
                android:id="@+id/number_seven"
                android:layout_width="0dp"
                android:layout_height="0dp"
                android:layout_columnWeight="1"
                android:layout_rowWeight="1"
                android:text="7"
                android:textSize="50sp"/>

            <Button
                android:id="@+id/number_eight"
                android:layout_width="0dp"
                android:layout_height="0dp"
                android:layout_columnWeight="1"
                android:layout_rowWeight="1"
                android:text="8"
                android:textSize="50sp"/>

            <Button
                android:id="@+id/number_nine"
                android:layout_width="0dp"
                android:layout_height="0dp"
                android:layout_columnWeight="1"
                android:layout_rowWeight="1"
                android:text="9"
                android:textSize="50sp"/>

            <Button
                android:id="@+id/operator_multiply"
                android:layout_width="0dp"
                android:layout_height="0dp"
                android:layout_columnWeight="1"
                android:layout_rowWeight="1"
                android:text="x"
                android:textSize="50sp"/>

            <Button
                android:id="@+id/number_four"
                android:layout_width="0dp"
                android:layout_height="0dp"
                android:layout_columnWeight="1"
                android:layout_rowWeight="1"
                android:text="4"
                android:textSize="50sp"/>

            <Button
                android:id="@+id/number_five"
                android:layout_width="0dp"
                android:layout_height="0dp"
                android:layout_columnWeight="1"
                android:layout_rowWeight="1"
                android:text="5"
                android:textSize="50sp"/>

            <Button
                android:id="@+id/number_six"
                android:layout_width="0dp"
                android:layout_height="0dp"
                android:layout_columnWeight="1"
                android:layout_rowWeight="1"
                android:text="6"
                android:textSize="50sp"/>

            <Button
                android:id="@+id/operator_subtract"
                android:layout_width="0dp"
                android:layout_height="0dp"
                android:layout_columnWeight="1"
                android:layout_rowWeight="1"
                android:text="—"
                android:textSize="50sp"/>

            <Button
                android:id="@+id/number_one"
                android:layout_width="0dp"
                android:layout_height="0dp"
                android:layout_columnWeight="1"
                android:layout_rowWeight="1"
                android:text="1"
                android:textSize="50sp"/>

            <Button
                android:id="@+id/number_two"
                android:layout_width="0dp"
                android:layout_height="0dp"
                android:layout_columnWeight="1"
                android:layout_rowWeight="1"
                android:text="2"
                android:textSize="50sp"/>

            <Button
                android:id="@+id/number_three"
                android:layout_width="0dp"
                android:layout_height="0dp"
                android:layout_columnWeight="1"
                android:layout_rowWeight="1"
                android:text="3"
                android:textSize="50sp"/>

            <Button
                android:id="@+id/operator_add"
                android:layout_width="0dp"
                android:layout_height="0dp"
                android:layout_columnWeight="1"
                android:layout_rowWeight="1"
                android:text="+"
                android:textSize="50sp"/>

            <Button
                android:id="@+id/number_zero"
                android:layout_width="0dp"
                android:layout_height="0dp"
                android:layout_columnWeight="1"
                android:layout_rowWeight="1"
                android:text="0"
                android:layout_columnSpan="2"
                android:textSize="50sp"/>

            <Button
                android:id="@+id/operator_point"
                android:layout_width="0dp"
                android:layout_height="0dp"
                android:layout_columnWeight="1"
                android:layout_rowWeight="1"
                android:text="."
                android:textSize="50sp"/>

            <Button
                android:id="@+id/operator_equal"
                android:layout_width="0dp"
                android:layout_height="0dp"
                android:layout_columnWeight="1"
                android:layout_rowWeight="1"
                android:text="="
                android:textSize="50sp"/>

        </GridLayout>
    </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

运行截图

[外链图片转存中…(img-VrCBhL2f-1588467324713)]

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值