简易计算器(加、减、乘、除、括号、小数&负数处理)(Java)

简易计算器(加、减、乘、除、括号、小数&负数处理)(Java)

文章目录

    • 简易计算器(加、减、乘、除、括号、小数&负数处理)(Java)
    • 0.参考
        • [颜色查询对照表](https://www.114la.com/other/rgb.htm)
    • 1.前言
    • 2.逻辑
    • 3.中缀表达式转为后缀表达式
    • 4.中缀表达式转为后缀表达式、运算
    • 5.处理项
        • 1.字体缩放
        • 2.圆形按钮设置
        • 3.负号的处理
        • 4.BigDecimal(小数运算精度问题)
        • 5.一个数字中只能使用一个小数点的问题
        • 6.删除所有内容还继续删除导致程序崩溃
        • 7.同时输入两个运算符
        • 8.输入不正确的表达式
    • 6.更改图标
        • 图片转为png格式
    • 7.打包成APK安装

0.参考

[颜色查询对照表](https://www.114la.com/other/rgb.htm)

1.前言

模仿苹果手机的计算器,以下是效果图
简易计算器(加、减、乘、除、括号、小数&负数处理)(Java)_第1张图片
单行显示字体缩小的效果

#布局
我采用了线性布局(个人认为百分比布局会更好)。
刚看完线性布局部分就迫不及待的开始写界面,写完所有按钮之后试图在一个线性布局中调整按钮的位置,想调整好真的难,后来才知道有线性布局的嵌套,用了嵌套才使得布局美丽了些。

计算器布局嵌套:在一个覆盖全部屏幕的布局中,嵌套两个布局,将屏幕分成两部分,再将下半部分按照行分成分成五个部分(你也可以按照列分),在布局中放入按钮。
简易计算器(加、减、乘、除、括号、小数&负数处理)(Java)_第2张图片

<?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"		//高匹配父布局
    android:layout_gravity="bottom"				//布局位与屏幕底部
    android:background="#000000">				//布局背景颜色
    <LinearLayout								//textview部分		
        android:orientation="vertical"			//水平分布
        android:layout_width="match_parent"
        android:layout_height="140dp">

        <TextView
            android:id="@+id/text_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="center"
            android:background="@null"					//不显示编辑框中的下划线
            android:cursorVisible="false"				//隐藏光标
            android:gravity="right|bottom"
            android:lines="1"							//限制单行显示
            android:textColor="#FFFFFF"					//字体颜色
            app:autoSizeMaxTextSize="80dp"				//最大字体
            app:autoSizeMinTextSize="20dp"				//最小字体
            app:autoSizeStepGranularity="4dp"			//每次缩小字体的幅度
            app:autoSizeTextType="uniform" />			//打开超过限制自动缩小字体的显示功能
    </LinearLayout>
    <LinearLayout										//按钮部分的那一大块
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="460dp"
        android:layout_gravity="bottom">
        <LinearLayout									//按钮部分按照行嵌套(第一行)
            android:orientation="horizontal"
        android:layout_width="match_parent"
            android:gravity="center"
        android:layout_height="90dp">
            <Button
                android:id="@+id/button_AC"
                android:layout_width="75dp"
                android:layout_height="75dp"
                android:background="@drawable/button_circle"		//自定义的圆形按钮
                android:text="AC"
                android:textColor="#000000"
                android:textSize="35dp"
                android:layout_margin="6dp"							//按钮与周围的距离
                android:backgroundTint="#FAFAFA"/>					//不同按钮的不同颜色
            <Button
                android:id="@+id/button_left"
                android:layout_width="75dp"
                android:layout_height="75dp"
                android:background="@drawable/button_circle"
                android:text="("
                android:textColor="#000000"
                android:textSize="35dp"
                android:layout_margin="6dp"
                android:backgroundTint="#FCFCFC"/>
            <Button
                android:id="@+id/button_right"
                android:layout_width="75dp"
                android:layout_height="75dp"
                android:background="@drawable/button_circle"
                android:text=")"
                android:textColor="#000000"
                android:textSize="35dp"
                android:layout_margin="6dp"
                android:backgroundTint="#FCFCFC" />
            <Button
                android:id="@+id/button_divide"
                android:layout_width="75dp"
                android:layout_height="75dp"
                android:background="@drawable/button_circle"
                android:text="÷"
                android:textColor="#FCFCFC"
                android:textSize="35dp"
                android:layout_margin="6dp"
                android:backgroundTint="#FF8C00"/>
    </LinearLayout>											//(第二行)
        <LinearLayout
            android:gravity="center"
            android:layout_width="match_parent"
            android:layout_height="90dp">
            <Button
                android:id="@+id/button_7"
                android:layout_width="75dp"
                android:layout_height="75dp"
                android:background="@drawable/button_circle"
                android:text="7"
                android:textColor="#FCFCFC"
                android:textSize="35dp"
                android:layout_margin="6dp"/>
            <Button
                android:id="@+id/button_8"
                android:layout_width="75dp"
                android:layout_height="75dp"
                android:background="@drawable/button_circle"
                android:text="8"
                android:textColor="#FCFCFC"
                android:textSize="35dp"
                android:layout_margin="6dp"/>
            <Button
                android:id="@+id/button_9"
                android:layout_width="75dp"
                android:layout_height="75dp"
                android:background="@drawable/button_circle"
                android:text="9"
                android:textColor="#FCFCFC"
                android:textSize="35dp"
                android:layout_margin="6dp"/>

            <Button
                android:id="@+id/button_multiple"
                android:layout_width="75dp"
                android:layout_height="75dp"
                android:layout_margin="6dp"
                android:background="@drawable/button_circle"
                android:backgroundTint="#FF8C00"
                android:text="×"
                android:textColor="#FCFCFC"
                android:textSize="35dp" />
        </LinearLayout>
        <LinearLayout												//(第三行)
            android:gravity="center"
            android:layout_width="match_parent"
            android:layout_height="90dp">
            <Button
                android:id="@+id/button_4"
                android:layout_width="75dp"
                android:layout_height="75dp"
                android:background="@drawable/button_circle"
                android:text="4"
                android:textColor="#FCFCFC"
                android:textSize="35dp"
                android:layout_margin="6dp"/>
            <Button
                android:id="@+id/button_5"
                android:layout_width="75dp"
                android:layout_height="75dp"
                android:background="@drawable/button_circle"
                android:text="5"
                android:textColor="#FCFCFC"
                android:textSize="35dp"
                android:layout_margin="6dp"/>
            <Button
                android:id="@+id/button_6"
                android:layout_width="75dp"
                android:layout_height="75dp"
                android:background="@drawable/button_circle"
                android:text="6"
                android:textColor="#FCFCFC"
                android:textSize="35dp"
                android:layout_margin="6dp"/>
            <Button
                android:id="@+id/button_minus"
                android:layout_width="75dp"
                android:layout_height="75dp"
                android:background="@drawable/button_circle"
                android:text="—"
                android:textColor="#FCFCFC"
                android:textSize="35dp"
                android:layout_margin="6dp"
                android:backgroundTint="#FF8C00"/>
        </LinearLayout>
        <LinearLayout													//(第四行)
            android:gravity="center"
            android:layout_width="match_parent"
            android:layout_height="90dp">
            <Button
                android:id="@+id/button_1"
                android:layout_width="75dp"
                android:layout_height="75dp"
                android:background="@drawable/button_circle"
                android:text="1"
                android:textColor="#FCFCFC"
                android:textSize="35dp"
                android:layout_margin="6dp"/>
            <Button
                android:id="@+id/button_2"
                android:layout_width="75dp"
                android:layout_height="75dp"
                android:background="@drawable/button_circle"
                android:text="2"
                android:textColor="#FCFCFC"
                android:textSize="35dp"
                android:layout_margin="6dp"/>
            <Button
                android:id="@+id/button_3"
                android:layout_width="75dp"
                android:layout_height="75dp"
                android:background="@drawable/button_circle"
                android:text="3"
                android:textColor="#FCFCFC"
                android:textSize="35dp"
                android:layout_margin="6dp"/>
            <Button
                android:id="@+id/button_add"
                android:layout_width="75dp"
                android:layout_height="75dp"
                android:background="@drawable/button_circle"
                android:text="+"
                android:textColor="#FCFCFC"
                android:textSize="35dp"
                android:layout_margin="6dp"
                android:backgroundTint="#FF8C00"/>
        </LinearLayout>
        <LinearLayout														//(第五行)
            android:gravity="center"
            android:layout_width="match_parent"
            android:layout_height="90dp">
            <Button
                android:id="@+id/button_0"
                android:layout_width="75dp"
                android:layout_height="75dp"
                android:background="@drawable/button_circle"
                android:text="0"
                android:textColor="#FCFCFC"
                android:textSize="35dp"
                android:layout_margin="6dp"/>
            <Button
                android:id="@+id/button_delete"
                android:layout_width="75dp"
                android:layout_height="75dp"
                android:background="@drawable/button_circle"
                android:text="del"
                android:textColor="#FCFCFC"
                android:textSize="35dp"
                android:layout_margin="6dp"/>

            <Button
                android:id="@+id/button_point"
                android:layout_width="75dp"
                android:layout_height="75dp"
                android:layout_margin="6dp"
                android:background="@drawable/button_circle"
                android:text="."
                android:textColor="#FCFCFC"
                android:textSize="35dp" />
            <Button
                android:id="@+id/button_equal"
                android:layout_width="75dp"
                android:layout_height="75dp"
                android:background="@drawable/button_circle"
                android:backgroundTint="#FF8C00"
                android:text="="
                android:textColor="#FCFCFC"
                android:textSize="35dp"
                android:layout_margin="6dp" />
        </LinearLayout>
    </LinearLayout>
</LinearLayout>

2.逻辑

给按钮设置监听,这里用借用R文件中的id使用switch做判断,再在case中添加逻辑

package com.example.caculatoractivity;								//这部分不用管,会自己导包进来

import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.text.Editable;
import android.text.InputType;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity implements View.OnClickListener{
    Button button_1;							//创建按钮
    Button button_2;
    Button button_3;
    Button button_4;
    Button button_5;
    Button button_6;
    Button button_7;
    Button button_8;
    Button button_9;
    Button button_0;
    Button button_AC;
    Button button_add;
    Button button_delete;
    Button button_equal;
    Button button_left;
    Button button_right;
    Button button_divide;
    Button button_multiple;
    Button button_point;
    Button button_minus;
    private TextView text_view;									//显示部分
    private StringBuilder pending=new StringBuilder();			//用于保存键入的内容

    private void initView() {									//布局内容的初始方法
         button_1=(Button)findViewById(R.id.button_1);			//按钮和输出框的对应
         button_2=(Button)findViewById(R.id.button_2);
         button_3=(Button)findViewById(R.id.button_3);
         button_4=(Button)findViewById(R.id.button_4);
         button_5=(Button)findViewById(R.id.button_5);
         button_6=(Button)findViewById(R.id.button_6);
         button_7=(Button)findViewById(R.id.button_7);
         button_8=(Button)findViewById(R.id.button_8);
         button_9=(Button)findViewById(R.id.button_9);
         button_0=(Button)findViewById(R.id.button_0);
         button_AC=(Button)findViewById(R.id.button_AC);
         button_add=(Button)findViewById(R.id.button_add);
         button_delete=(Button)findViewById(R.id.button_delete);
         button_equal=(Button)findViewById(R.id.button_equal);
         button_left=(Button)findViewById(R.id.button_left);
         button_right=(Button)findViewById(R.id.button_right);
         button_divide=(Button)findViewById(R.id.button_divide);
         button_multiple=(Button)findViewById(R.id.button_multiple);
         button_point=(Button)findViewById(R.id.button_point);
         button_minus=(Button)findViewById(R.id.button_minus);
        text_view=(TextView) findViewById(R.id.text_view);

        button_0.setOnClickListener(this);
        button_1.setOnClickListener(this);
        button_2.setOnClickListener(this);
        button_3.setOnClickListener(this);
        button_4.setOnClickListener(this);
        button_5.setOnClickListener(this);
        button_6.setOnClickListener(this);
        button_7.setOnClickListener(this);
        button_8.setOnClickListener(this);
        button_9.setOnClickListener(this);
        button_AC.setOnClickListener(this);
        button_add.setOnClickListener(this);
        button_delete.setOnClickListener(this);
        button_divide.setOnClickListener(this);
        button_equal.setOnClickListener(this);
        button_left.setOnClickListener(this);
        button_multiple.setOnClickListener(this);
        button_point.setOnClickListener(this);
        button_right.setOnClickListener(this);
        button_delete.setOnClickListener(this);
        button_minus.setOnClickListener(this);
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {			//OnCreat方法的重写(每个活动中都要重写该方法)
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ActionBar actionBar=getSupportActionBar();
        if(actionBar!=null) {
            actionBar.hide();
        }
        initView();
        text_view=(TextView) findViewById(R.id.text_view);
        text_view.setOnTouchListener(new View.OnTouchListener() {			
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {		//通过对onTouch方法的重写关闭软键盘
                text_view.setInputType(InputType.TYPE_NULL);
                return false;
            }
        });
    }
    boolean point=true;												//用于判断在开头不能输入小数点和同一个数字不能输入多个小数点
    boolean equal=true;												//用于计算完毕后是否需要清屏(继续运算/开始新的运算)
    @Override
    public void onClick(View view) {								//对各个按钮的监听
        int last=0;								//忘记了是干啥的?
        if(pending.length()!=0) {
            last = pending.codePointAt(pending.length() - 1);
        }
        switch (view.getId()) {
            case R.id.button_0:
                if(equal==true) {								
                    if(zero==true) {
                        if(pending.length()==0) {
                            zero=false;
                        }
                        pending = pending.append("0");        //延长要被分析的字符串
                        text_view.setText(pending);         //将按钮上显示的内容显示到EditText部分
                    }
                }else {
                    equal=true;
                pending=pending.delete(0,pending.length());
                pending=pending.append("0");
                text_view.setText(pending);
            }
                break;
            case R.id.button_1:
                if(equal==true) {
                if(pending.charAt(pending.length()-1)==')'){
                        pending=pending.append("×");
                    }
                    pending = pending.append("1");
                    text_view.setText(pending);
                }else {
                    equal=true;
                    pending=pending.delete(0,pending.length());
                    pending = pending.append("1");
                    text_view.setText(pending);
                }
                break;
            case R.id.button_2:
                if(equal==true) {
                if(pending.charAt(pending.length()-1)==')'){
                        pending=pending.append("×");
                    }
                    pending = pending.append("2");
                    text_view.setText(pending);
                }else {
                    equal=true;
                    pending=pending.delete(0,pending.length());
                    pending = pending.append("2");
                    text_view.setText(pending);
                }
                break;
            case R.id.button_3:
                if(equal==true) {
                if(pending.charAt(pending.length()-1)==')'){
                        pending=pending.append("×");
                    }
                    pending = pending.append("3");
                    text_view.setText(pending);
                }else {
                    equal=true;
                    pending=pending.delete(0,pending.length());
                    pending = pending.append("3");
                    text_view.setText(pending);
                }
                break;
            case R.id.button_4:
                if(equal==true) {
                if(pending.charAt(pending.length()-1)==')'){
                        pending=pending.append("×");
                    }
                    pending = pending.append("4");
                    text_view.setText(pending);
                }else {
                    equal=true;
                    pending=pending.delete(0,pending.length());
                    pending = pending.append("4");
                    text_view.setText(pending);
                }
                break;
            case R.id.button_5:
                if(equal==true) {
                if(pending.charAt(pending.length()-1)==')'){
                        pending=pending.append("×");
                    }
                    pending = pending.append("5");
                    text_view.setText(pending);
                }else {
                    equal=true;
                    pending=pending.delete(0,pending.length());
                    pending = pending.append("5");
                    text_view.setText(pending);
                }
                break;
            case R.id.button_6:
                if(equal==true) {
                if(pending.charAt(pending.length()-1)==')'){
                        pending=pending.append("×");
                    }
                    pending = pending.append("6");
                    text_view.setText(pending);
                }else {
                    equal=true;
                    pending=pending.delete(0,pending.length());
                    pending = pending.append("6");
                    text_view.setText(pending);
                }
                break;
            case R.id.button_7:
                if(equal==true) {
                if(pending.charAt(pending.length()-1)==')'){
                        pending=pending.append("×");
                    }
                    pending = pending.append("7");
                    text_view.setText(pending);
                }else {
                    equal=true;
                    pending=pending.delete(0,pending.length());
                    pending = pending.append("7");
                    text_view.setText(pending);
                }
                break;
            case R.id.button_8:
                if(equal==true) {
                if(pending.charAt(pending.length()-1)==')'){
                        pending=pending.append("×");
                    }
                    pending = pending.append("8");
                    text_view.setText(pending);
                }else {
                    equal=true;
                    pending=pending.delete(0,pending.length());
                    pending = pending.append("8");
                    text_view.setText(pending);
                }
                break;
            case R.id.button_9:
                if(equal==true) {
                if(pending.charAt(pending.length()-1)==')'){
                        pending=pending.append("×");
                    }
                    pending = pending.append("9");
                    text_view.setText(pending);
                }else {
                    equal=true;
                    pending=pending.delete(0,pending.length());
                    pending = pending.append("9");
                    text_view.setText(pending);
                }
                break;
            case R.id.button_AC:
                point=true;
                equal=true;
                pending=pending.delete(0,pending.length());
                text_view.setText(pending);
                break;
            case R.id.button_add:
                point=true;
                equal=true;
                if(pending.length()!=0) {					//优化处理(输入两个运算符时)
                    if(pending.charAt(pending.length()-1)=='×'||pending.charAt(pending.length()-1)=='-'||pending.charAt(pending.length()-1)=='÷'||pending.charAt(pending.length()-1)=='+') {
                        pending=pending.deleteCharAt(pending.length()-1);
                    }
                    pending = pending.append("+");
                }
                text_view.setText(pending);
                break;
            case R.id.button_delete:
                if(pending.length()==0) {							//解决没内容可以删除按删除崩溃问题
                    return;
                }
                    pending = pending.delete(pending.length() - 1, pending.length());
                text_view.setText(pending);
                break;
            case R.id.button_divide:
                equal=true;
                point=true;
                if(pending.length()!=0) {
                    if(pending.charAt(pending.length()-1)=='+'||pending.charAt(pending.length()-1)=='-'||pending.charAt(pending.length()-1)=='×'||pending.charAt(pending.length()-1)=='÷') {
                        pending=pending.deleteCharAt(pending.length()-1);
                    }
                    pending = pending.append("÷");
                }
                text_view.setText(pending);
                break;
            case R.id.button_multiple:
                point=true;
                equal=true;
                if(pending.length()!=0) {
                    if(pending.charAt(pending.length()-1)=='+'||pending.charAt(pending.length()-1)=='-'||pending.charAt(pending.length()-1)=='÷'||pending.charAt(pending.length()-1)=='×') {
                        pending=pending.deleteCharAt(pending.length()-1);
                    }
                    pending = pending.append("×");
                }
                text_view.setText(pending);
                break;
            case R.id.button_minus:
                point=true;
                equal=true;
                    pending = pending.append("-");
                text_view.setText(pending);
                break;
            case R.id.button_equal:									//算法部分
                point=true;
                //equal=false;
                if((pending.length()>1)) {
                    InFixInToDuffix inf =new InFixInToDuffix();
                    String result;
                    try {											//异常处理
                        String a=inf.toSuffix(pending);
                        result=inf.dealEquation(a);
                        if(a.length()==0) {							//如果经过运算以后的结果为空,要处理为异常,否则会崩溃
                            result="error";
                        }
                    }catch (Exception ex) {
                        result="error";
                    }
                    text_view.setText(result);
                    pending=pending.delete(0,pending.length());
                    if(Character.isDigit(result.charAt(0))||Character.isDigit(result.charAt(1))) {			//处理计算结果为负不能再继续运算的问题
                        equal=false;
                        pending=pending.append(result);
                    }
                }
                break;
            case R.id.button_left:
                point=true;
                if(pending.length()>0&&pending.charAt(pending.length()-1)=='-') {		//解决括号外面有负号运算会错误的问题
                    pending=pending.append("1×");
                }
                if(pending.length()>0&&pending.charAt(pending.length()-1)>='0'&&pending.charAt(pending.length()-1)<='9'){
                    pending=pending.append("×");					//优化比如:8(2+1)识别为8*(2+1)
                    }
                pending=pending.append("(");
                text_view.setText(pending);
                break;
            case R.id.button_right:
                point=true;
                if(pending.length()!=0) {
                    pending = pending.append(")");
                    text_view.setText(pending);
                }
                break;
            case R.id.button_point:
            	zero=true;
                if(pending.length()!=0) {
                    if(point==true) {
                        pending = pending.append(".");
                        text_view.setText(pending);
                    }
                }
                point = false;
                break;
            default:
                break;
        }

3.中缀表达式转为后缀表达式

这里贴别人的
中缀表达式转后缀表达式的步骤:www.cnblogs.com/james111/p/7027820.html

4.中缀表达式转为后缀表达式、运算

package com.example.caculatoractivity;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class InFixInToDuffix {
    //使用集合定义好符号的运算优先级别
    private static final Map<Character, Integer> basic = new HashMap<Character, Integer>();

    static {
        basic.put('-', 1);
        basic.put('+', 1);
        basic.put('×', 2);
        basic.put('÷', 2);
        basic.put('(', 0);//在运算中  ()的优先级最高,但是此处因程序中需要 故设置为0
    }


    //将中缀表达式转换为后缀表达式
    public String toSuffix(StringBuilder infix) {
        List<String> queue = new ArrayList<>();                                    //定义队列  用于存储 数字  以及最后的  后缀表达式
        List<Character> stack = new ArrayList<Character>();                             //定义栈    用于存储  运算符  最后stack中会被 弹空
        char[] charArr = infix.substring(0, infix.length()).trim().toCharArray();                                    //字符数组  用于拆分数字或符号
        String standard = "×÷+-()";                                                        //判定标准 将表达式中会出现的运算符写出来
        char ch = '&';                                                                    //在循环中用来保存 字符数组的当前循环变量的  这里仅仅是初始化一个值  没有意义
        int len = 0;                                                                    //用于记录字符长度 【例如100*2,则记录的len为3 到时候截取字符串的前三位就是数字】
        for (int i = 0; i < charArr.length; i++) {                                        //开始迭代
            ch = charArr[i];                                                            //保存当前迭代变量
            if(i==0&&ch=='-') {										//开头是负号的处理
                queue.add("0");
            }
            if (Character.isDigit(ch)) {                                                    //如果当前变量为 数字
                len++;
            }else if (ch == '.') {                                                        //如果当前变量为  .  会出现在小数里面
                len++;
            } else if(ch=='-'&&i!=0&&charArr[i-1]!=')'&&standard.indexOf(charArr[i-1])!=-1) {
                    len++;
            } else if (standard.indexOf(ch) != -1) {                                        //如果是上面标准中的 任意一个符号
                if (len > 0) {                                                            //长度也有
                    queue.add(String.valueOf(Arrays.copyOfRange(charArr, i - len, i)));    //说明符号之前的可以截取下来做数字
                    len = 0;                                                            //长度置空
                }
                if (ch == '(') {                                                            //如果是左括号
                    stack.add(ch);                                                        //将左括号 放入栈中
                    continue;                                                            //跳出本次循环  继续找下一个位置
                }
                if (!stack.isEmpty()) {                                                    //如果栈不为empty
                    int size = stack.size() - 1;                                        //获取栈的大小-1  即代表栈最后一个元素的下标
                    boolean flag = false;                                                //设置标志位
                    while (size >= 0 && ch == ')' && stack.get(size) != '(') {            //若当前ch为右括号,则 栈里元素从栈顶一直弹出,直到弹出到 左括号
                        queue.add(String.valueOf(stack.remove(size)));                    //注意此处条件:ch并未入栈,所以并未插入队列中;同样直到找到左括号的时候,循环结束了,所以左括号也不会放入队列中【也就是:后缀表达式中不会出现括号】
                        size--;                                                            //size-- 保证下标永远在栈最后一个元素【栈中概念:指针永远指在栈顶元素】
                        flag = true;                                                    //设置标志位为true  表明一直在取()中的元素
                    }
                    if (ch == ')' && stack.get(size) == '(') {
                        flag = true;
                    }
                    while (size >= 0 && !flag && basic.get(stack.get(size)) >= basic.get(ch)) {    //若取得不是()内的元素,并且当前栈顶元素的优先级>=对比元素 那就出栈插入队列
                        queue.add(String.valueOf(stack.remove(size)));                    //同样  此处也是remove()方法,既能得到要获取的元素,也能将栈中元素移除掉
                        size--;
                    }
                }
                if (ch != ')') {                                                            //若当前元素不是右括号
                    stack.add(ch);                                                        //就要保证这个符号 入栈
                } else {                                                                //否则就要出栈 栈内符号
                    stack.remove(stack.size() - 1);
                }
            }
            if (i == charArr.length - 1) {                                                //如果已经走到了  中缀表达式的最后一位
                if (len > 0) {                                                            //如果len>0  就截取数字
                    queue.add(String.valueOf(Arrays.copyOfRange(charArr, i - len + 1, i + 1)));
                }
                int size = stack.size() - 1;                                            //size表示栈内最后一个元素下标
                while (size >= 0) {                                                        //一直将栈内  符号全部出栈 并且加入队列中  【最终的后缀表达式是存放在队列中的,而栈内最后会被弹空】
                    queue.add(String.valueOf(stack.remove(size)));
                    size--;
                }
            }

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


    public String dealEquation(String equation) {

        String[] arr = equation.split(", ");                                    //根据, 拆分字符串
        List<String> list = new ArrayList<String>();                            //用于计算时  存储运算过程的集合【例如list中当前放置  100   20  5  /  则取出20/5 最终将结果4存入list   此时list中结果为  100  4 】
        int size=0;
        for (int i = 0; i < arr.length; i++) {                                    //此处就是上面说的运算过程, 因为list.remove的缘故,所以取出最后一个数个最后两个数  都是size-2
            size = list.size();
            switch (arr[i]) {
                case "+":
                    BigDecimal a = new BigDecimal(list.remove(size - 2));
                    BigDecimal a1=new BigDecimal(list.remove(size - 2));
                    list.add(String.valueOf(a.add(a1)));
                    break;
                case "-":
                    BigDecimal b = new BigDecimal(list.remove(size - 2)); //list.remove()的返回值相乘
                    BigDecimal b1=new BigDecimal(list.remove(size-2));
                    list.add(String.valueOf(b.subtract(b1)));
                    break;
                case "×":
                    BigDecimal c=new BigDecimal(list.remove(size-2));
                    BigDecimal c1=new BigDecimal(list.remove(size-2));
                    list.add(String.valueOf(c.multiply(c1)));
                    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,6, BigDecimal.ROUND_HALF_UP).doubleValue()));
                    break;
                default:
                    list.add(String.valueOf(arr[i]));
                    break;                                    //如果是数字  直接放进list中
            }
        }

        return list.size()


                == 1 ? list.get(0) : "运算失败";                    //最终list中仅有一个结果,否则就是算错了
    }
}


5.处理项

1.字体缩放

在布局下添加app代码
简易计算器(加、减、乘、除、括号、小数&负数处理)(Java)_第3张图片
然后就可以在属性中添加
注意:设置为单行才可以缩小
简易计算器(加、减、乘、除、括号、小数&负数处理)(Java)_第4张图片

2.圆形按钮设置

在app->src->res->drawable中添加文件
在这里插入图片描述
添加方式
简易计算器(加、减、乘、除、括号、小数&负数处理)(Java)_第5张图片

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <corners android:radius="480dp"/>
    <solid android:color="#707070"/>
</shape>

使用
简易计算器(加、减、乘、除、括号、小数&负数处理)(Java)_第6张图片

3.负号的处理

我的负号处理是有缺陷的(显示问题),这里要考虑到数字前面的负号和括号前面的负号。
首先应该区分“-”在表达式中是负号还是减号,另外要将负号在开头和表达式中分开处理,我的处理方式是如果遇到负号就把负号替换成-1×,但是这样显示的时候也会出现-1×

4.BigDecimal(小数运算精度问题)

处理小数运算的精度问题,如果用double型的话,在小数运算时会失精度(原因:计算机底层以2进制运算)
具体的用法、参数在API中查看靠谱些

5.一个数字中只能使用一个小数点的问题

思路:定义一个初始为true的布尔类型的变量,在输入一次小数点之后就更新该变量为false,直到遇到运算符或者括号、等号、清零时再更新为ture,表示已经时另外一个数字,可以继续输入小数点。

####开始时候不能一直输入零的问题

没有一个计算器可以输入很多零作为无效数字,除非是0.00000…1之类,所以在输入数字时应该做是不是一直在输入零的判断,做出相应的处理,定义一个boolean类型用来判断是不是输入了“.”输入“.”以后则可以继续输入零

6.删除所有内容还继续删除导致程序崩溃

在相应的删除逻辑中判断存入的字符串是不是空的,如果是空的,就不能进行删除操作

####加乘除不能在还没有输入数字时输入

和删除的判断一致

7.同时输入两个运算符

思路:这种输入肯定时不被允许的,我的处理是,用后一个运算符将前一个运算符覆盖

8.输入不正确的表达式

输入不正确的表达式时,应该进行异常处理(try catch),否则程序会崩溃,具体操作可以自行了解

6.更改图标

首先你需要一张png的图片

图片转为png格式

打开电脑自带画图
在这里插入图片描述
插入图片
简易计算器(加、减、乘、除、括号、小数&负数处理)(Java)_第7张图片
保存
简易计算器(加、减、乘、除、括号、小数&负数处理)(Java)_第8张图片

  • app->scr->main下放入图片(png)
    简易计算器(加、减、乘、除、括号、小数&负数处理)(Java)_第9张图片
    进行图片的插入样式设置
    简易计算器(加、减、乘、除、括号、小数&负数处理)(Java)_第10张图片
  • 修改AndroidManifest.xml文件中资源指向
    简易计算器(加、减、乘、除、括号、小数&负数处理)(Java)_第11张图片

7.打包成APK安装

简易计算器(加、减、乘、除、括号、小数&负数处理)(Java)_第12张图片
简易计算器(加、减、乘、除、括号、小数&负数处理)(Java)_第13张图片
简易计算器(加、减、乘、除、括号、小数&负数处理)(Java)_第14张图片
第一栏开发者名称写一下就可以了
简易计算器(加、减、乘、除、括号、小数&负数处理)(Java)_第15张图片
简易计算器(加、减、乘、除、括号、小数&负数处理)(Java)_第16张图片
打包完成后,app->release下有个APK文件,右键
简易计算器(加、减、乘、除、括号、小数&负数处理)(Java)_第17张图片
点进去,把APK文件发送到手机安装就好

你可能感兴趣的:(Android)