安卓开发 科学计算器

说明

代码逻辑部分是copy的,为了应付课设,就自己弄个布局,本人小白啥也不懂,参考
链接链接地址

运行结果

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

activity_main.xml

<?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">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:layout_editor_absoluteX="0dp"
        tools:layout_editor_absoluteY="0dp">

        <EditText
            android:id="@+id/editView"
            android:layout_width="360dp"
            android:layout_height="80dp"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="10dp"
            android:background="@drawable/border"
            android:editable="false"
            android:gravity="bottom|right"
            android:hint="please enter..."
            android:textSize="24sp" />

        <GridLayout
            android:id="@+id/GridLayout1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/editView"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="20dp"
            android:columnCount="4"
            android:orientation="horizontal"
            android:rowCount="9">

            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:onClick="clickButton"
                android:text="(" />

            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:onClick="clickButton"
                android:text=")" />

            <Button
                android:layout_width="174dp"
                android:layout_columnSpan="2"
                android:onClick="delete"
                android:text="删除" />

            <Button
                android:onClick="square"
                android:text="x^2" />

            <Button
                android:onClick="cube"
                android:text="x^3" />

            <Button
                android:id="@+id/button18"
                android:layout_width="175dp"
                android:layout_height="wrap_content"
                android:layout_columnSpan="2"
                android:onClick="empty"
                android:text="清空" />

            <Button
                android:onClick="power"
                android:text="x^y" />

            <Button
                android:onClick="factorial"
                android:text="x!" />

            <Button
                android:onClick="squareRoot"
                android:text="" />

            <Button
                android:onClick="ln"
                android:text="ln" />

            <Button
                android:onClick="log"
                android:text="log" />

            <Button
                android:onClick="eulerNumber"
                android:text="e" />

            <Button
                android:onClick="sin"
                android:text="sin" />

            <Button
                android:onClick="cos"
                android:text="cos" />

            <Button
                android:onClick="tan"
                android:text="tan" />

            <Button
                android:onClick="pi"
                android:text="π" />

            <Button
                android:onClick="reciprocal"
                android:text="1/x" />

            <Button
                android:onClick="percentage"
                android:text="%" />

            <Button
                android:onClick="clickButton"
                android:text="+" />

            <Button
                android:onClick="clickButton"
                android:text="1" />

            <Button
                android:onClick="clickButton"
                android:text="2" />

            <Button
                android:onClick="clickButton"
                android:text="3" />

            <Button
                android:onClick="clickButton"
                android:text="-" />

            <Button
                android:onClick="clickButton"
                android:text="4" />

            <Button
                android:onClick="clickButton"
                android:text="5" />

            <Button
                android:onClick="clickButton"
                android:text="6" />

            <Button
                android:onClick="clickButton"
                android:text="*" />

            <Button
                android:onClick="clickButton"
                android:text="7" />

            <Button
                android:onClick="clickButton"
                android:text="8" />

            <Button
                android:onClick="clickButton"
                android:text="9" />

            <Button
                android:onClick="clickButton"
                android:text="/" />

            <Button
                android:onClick="clickButton"
                android:text="." />

            <Button
                android:onClick="clickButton"
                android:text="0" />

            <Button
                android:onClick="equal"
                android:text="=" />

        </GridLayout>

        <TextView
            android:id="@+id/textView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_centerHorizontal="true"
            android:layout_marginBottom="10dp"
            android:textColor="#FF0000"
            android:textSize="20sp" />
    </RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

MainActivity.java

package com.example.calculator;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

import android.widget.TextView;

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

public class MainActivity extends AppCompatActivity {
    private EditText editText;
    private TextView text;  //输入格式错误提示
    private Button button;
    private StringBuilder str = new StringBuilder();  //参与运算的式子
    private int indexYN = 0;    //是否出错的标志

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        editText = (EditText) findViewById(R.id.editView);
        text = (TextView) findViewById(R.id.textView);
    }

    //数字及符号按钮
    public void clickButton(View view){
        button = (Button) view;
        editText.append(button.getText());
        str.append(button.getText());
    }

    //清空
    public void empty(View view){
        editText.setText(null);
        str.delete(0,str.length());
    }

    //删除
    public void delete(View view){
        String nowText = editText.getText().toString();
        if(nowText.length()!=0&&str.length()!=0){
            editText.setText(nowText.substring(0,nowText.length()-1));
            str.deleteCharAt(str.length()-1);
        }
    }

    //等于
    public void equal(View view){
        indexYN = 0;
        System.out.println("str:\t"+str);
        System.out.println("lenth:\t"+str.length());
        estimate();
        if(indexYN==0){
            List<String> zhongZhui = zhuanZhongZhui(str.toString());
            System.out.println(zhongZhui);
            List<String> houZhui = zhuanHouZhui(zhongZhui);
            System.out.println(houZhui);
            editText.append("\n"+math(houZhui));
            str.delete(0,str.length());
            str.append(math(houZhui));
        }
    }

    //倒数
    public void reciprocal(View view){
        editText.append("1/");
        str.append("1/");
    }

    //阶乘
    public void factorial(View view){
        editText.append("!");
        str.append("!");
    }

    //平方
    public void square(View view){
        editText.append("^2");
        str.append("^2");
    }

    //立方
    public void cube(View view){
        editText.append("^3");
        str.append("^3");
    }

    //幂运算
    public void power(View view){
        editText.append("^");
        str.append("^");
    }

    //开方
    public void squareRoot(View view){
        editText.append("√");
        str.append("g");
    }

    //欧拉数e
    public void eulerNumber(View view){
        editText.append("e");
        str.append("e");
    }

    //百分数
    public void percentage(View view){
        editText.append("%");
        str.append("*0.01");
    }

    //圆周率
    public void pi(View view){
        editText.append("π");
        str.append("p");
    }

    //sin
    public void sin(View view){
        editText.append("sin");
        str.append("s");
    }

    //cos
    public void cos(View view){
        editText.append("cos");
        str.append("c");
    }

    //tan
    public void tan(View view){
        editText.append("tan");
        str.append("t");
    }

    //ln
    public void ln(View view){
        editText.append("ln");
        str.append("l");
    }

    //log
    public void log(View view){
        editText.append("log");
        str.append("o");
    }

    private List<String> zhuanZhongZhui(String str) {
        //把输入的字符串转换成中缀表达式。存入list中
        int index = 0;
        List<String> list = new ArrayList<>();
        do{
            char ch = str.charAt(index);
            if("+-*/^!logsct()".indexOf(str.charAt(index)) >= 0){
                //是操作符,直接添加至list中
                index ++;
                list.add(ch+"");
            }else if (str.charAt(index) == 'e' || str.charAt(index) == 'p'){
                index ++;
                list.add(ch+"");
            } else if("0123456789".indexOf(str.charAt(index)) >= 0){
                //是数字,判断多位数的情况
                String str1 = "";
                while (index < str.length() && "0123456789.".indexOf(str.charAt(index)) >= 0){
                    str1 += str.charAt(index);
                    index ++;
                }
                list.add(str1);

            }
        }while (index < str.length());
        return list;
    }

    public List<String> zhuanHouZhui(List<String> list){//中缀表达式转换称后缀表达式
        Stack<String> fuZhan = new Stack<>();
        List<String> list2 = new ArrayList<>();
        if (!list.isEmpty()) {
            for (int i = 0; i < list.size(); i++) {
                if (isNumber(list.get(i))){
                    list2.add(list.get(i));
                } else if (list.get(i).charAt(0) == '('){
                    fuZhan.push(list.get(i));
                } else if (isOperator(list.get(i)) && list.get(i).charAt(0) != '('){
                    if (fuZhan.isEmpty()){
                        fuZhan.push(list.get(i));
                    } else {//符栈不为空
                        if (list.get(i).charAt(0) != ')'){
                            if (adv(fuZhan.peek()) <= adv(list.get(i))){
                                //入栈
                                fuZhan.push(list.get(i));
                            } else {//出栈
                                while (!fuZhan.isEmpty() && !"(".equals(fuZhan.peek())){
                                    if(adv(list.get(i)) <= adv(fuZhan.peek())){
                                        list2.add(fuZhan.pop());
                                    }
                                }
                                if (fuZhan.isEmpty() || fuZhan.peek().charAt(0) == '('){
                                    fuZhan.push(list.get(i));
                                }
                            }
                        } else if (list.get(i).charAt(0) == ')'){
                            while (fuZhan.peek().charAt(0) != '('){
                                list2.add(fuZhan.pop());
                            }
                            fuZhan.pop();
                        }
                    }
                }
            }
            while (!fuZhan.isEmpty()){
                list2.add(fuZhan.pop());
            }
        } else {
            editText.setText("");
        }
        return list2;
    }
    public static boolean isOperator(String op){//判断是否为操作符
        if ("0123456789.ep".indexOf(op.charAt(0)) == -1) {
            return true;
        } else {
            return false;
        }
    }
    public static boolean isNumber(String num){//判断是否为操作数
        if ("0123456789ep".indexOf(num.charAt(0)) >= 0) {
            return true;
        } else {
            return false;
        }
    }
    public static int adv(String f){//判断操作符的优先级
        int result = 0;
        switch(f) {
            case "+":
                result = 1;
                break;
            case "-":
                result = 1;
                break;
            case "*":
                result = 2;
                break;
            case "/":
                result = 2;
                break;
            case "^":
                result = 3;
                break;
            case "!":
                result = 4;
                break;
            case "g":
                result = 4;
                break;
            case "l":
                result = 4;
                break;
            case "o":
                result = 4;
                break;
            case "s":
                result = 4;
                break;
            case "c":
                result = 4;
                break;
            case "t":
                result = 4;
                break;

        }
        return result;
    }

    public double math(List<String> list2) {//通过后缀表达式进行计算
        Stack<String> stack = new Stack<String>();
        for (int i = 0; i < list2.size(); i++) {
            if (isNumber(list2.get(i))) {
                if (list2.get(i).charAt(0) == 'e'){
                    stack.push(String.valueOf(Math.E));
                } else if (list2.get(i).charAt(0) == 'p'){
                    stack.push(String.valueOf(Math.PI));
                } else {
                    stack.push(list2.get(i));
                }
            } else if (isOperator(list2.get(i))){
                double res = 0;
                if (list2.get(i).equals("+")) {
                    double num2 = Double.parseDouble(stack.pop());
                    double num1 = Double.parseDouble(stack.pop());
                    res = num1 + num2;
                } else if (list2.get(i).equals("-")) {
                    double num2 = Double.parseDouble(stack.pop());
                    double num1 = Double.parseDouble(stack.pop());
                    res = num1 - num2;
                } else if (list2.get(i).equals("*")) {
                    double num2 = Double.parseDouble(stack.pop());
                    double num1 = Double.parseDouble(stack.pop());
                    res = num1 * num2;
                } else if (list2.get(i).equals("/")) {
                    double num2 = Double.parseDouble(stack.pop());
                    double num1 = Double.parseDouble(stack.pop());
                    if (num2 != 0){
                        res = num1 / num2;
                    } else {
                        editText.setText("除数不能为0");
                        indexYN = 1;
                    }
                } else if (list2.get(i).equals("^")) {
                    double num2 = Double.parseDouble(stack.pop());
                    double num1 = Double.parseDouble(stack.pop());
                    res = Math.pow(num1, num2);
                } else if (list2.get(i).equals("!")) {
                    double num1 = Double.parseDouble(stack.pop());
                    if (num1 == 0 || num1 == 1){
                        res = 1;
                    } else if (num1 == (int)num1 && num1 > 1){
                        int d = 1;
                        for (int j = (int)num1; j >0; j--) {
                            d *= j;
                        }
                        res = d;
                    } else {
                        editText.setText("阶乘必须为自然数");
                        indexYN = 1;
                    }
                } else if (list2.get(i).equals("g")) {
                    double num1 = Double.parseDouble(stack.pop());
                    res = Math.sqrt(num1);
                } else if (list2.get(i).equals("l")) {
                    double num1 = Double.parseDouble(stack.pop());
                    if (num1 > 0){
                        res = Math.log(num1);
                    } else {
                        editText.setText("ln的x必须大于0");
                        indexYN = 1;
                    }
                } else if (list2.get(i).equals("o")) {
                    double num1 = Double.parseDouble(stack.pop());
                    if (num1 > 0){
                        res = Math.log(num1) / Math.log(2);
                    } else {
                        editText.setText("log的x必须大于0");
                        indexYN = 1;
                    }
                } else if (list2.get(i).equals("s")) {
                    double num1 = Double.parseDouble(stack.pop());
                    res = Math.sin(num1);
                } else if (list2.get(i).equals("c")) {
                    double num1 = Double.parseDouble(stack.pop());
                    res = Math.cos(num1);
                } else if (list2.get(i).equals("t")) {
                    double num1 = Double.parseDouble(stack.pop());
                    if (Math.cos(num1) != 0){
                        res = Math.tan(num1);
                    } else {
                        editText.setText("tan的x不能为+-(π/2 + kπ)");
                        indexYN = 1;
                    }
                }
                stack.push("" + res);
            }
        }
        if (indexYN == 0){
            if (!stack.isEmpty()){
                return Double.parseDouble(stack.pop());
            } else {
                return 0;
            }
        } else {
            return -999999;
        }
    }

    public void estimate(){//判断输入是否错误
        int i = 0;
        if (str.length() == 0){
            text.setText("输入为空!");
            indexYN = 1;
        }
        if (str.length() == 1){
            //当只有一位字符时,只能是“0123456789ep”中的一个
            if ("0123456789ep".indexOf(str.charAt(0)) == -1){
                text.setText("输入错误!");
                indexYN = 1;
            }
        }
        if (str.length() > 1){
            for (i = 0; i < str.length() - 1; i++) {
                //1.第一个字符只能为"losctg(0123456789ep"中的一个
                if ("losctg(0123456789ep".indexOf(str.charAt(0)) == -1){
                    text.setText("输入错误!");
                    indexYN = 1;
                }
                //2.“+-*/”后面只能是"0123456789losctg(ep"中的一个
                if ("+-*/".indexOf(str.charAt(i)) >= 0 && "0123456789losctg(ep".indexOf(str.charAt(i + 1)) == -1){
                    text.setText("输入错误!");
                    indexYN = 1;
                }
                //3."."后面只能是“0123456789”中的一个
                if (str.charAt(i) == '.' && "0123456789".indexOf(str.charAt(i + 1)) == -1){
                    text.setText("输入错误!");
                    indexYN = 1;
                }
                //4."!"后面只能是“+-*/^)”中的一个
                if (str.charAt(i) == '!' && "+-*/^)".indexOf(str.charAt(i + 1)) == -1){
                    text.setText("输入错误!");
                    indexYN = 1;
                }
                //5."losctg"后面只能是“0123456789(ep”中的一个
                if ("losctg".indexOf(str.charAt(i)) >= 0 && "0123456789(ep".indexOf(str.charAt(i + 1)) == -1){
                    text.setText("输入错误!");
                    indexYN = 1;
                }
                //6."0"的判断操作
                if (str.charAt(0) == '0' && str.charAt(1) == '0'){
                    text.setText("输入错误!");
                    indexYN = 1;
                }
                if (i >= 1 && str.charAt(i) == '0'){
                    //&& str.charAt(0) == '0' && str.charAt(1) == '0'
                    int m = i;
                    int n = i;
                    int is = 0;
                    //1.当0的上一个字符不为"0123456789."时,后一位只能是“+-*/.!^)”中的一个
                    if ("0123456789.".indexOf(str.charAt(m - 1)) == -1 && "+-*/.!^)".indexOf(str.charAt(i + 1)) == -1){
                        text.setText("输入错误!");
                        indexYN = 1;
                    }
                    //2.如果0的上一位为“.”,则后一位只能是“0123456789+-*/.^)”中的一个
                    if (str.charAt(m - 1) == '.' && "0123456789+-*/.^)".indexOf(str.charAt(i + 1)) == -1){
                        text.setText("输入错误!");
                        indexYN = 1;
                    }
                    n -= 1;
                    while (n > 0){
                        if ("(+-*/^glosct".indexOf(str.charAt(n)) >= 0){
                            break;
                        }
                        if (str.charAt(n) == '.'){
                            is++;
                        }
                        n--;
                    }

                    //3.如果0到上一个运算符之间没有“.”的话,整数位第一个只能是“123456789”,
                    //  且后一位只能是“0123456789+-*/.!^)”中的一个。
                    if ((is == 0 && str.charAt(n) == '0') || "0123456789+-*/.!^)".indexOf(str.charAt(i + 1)) == -1){
                        text.setText("输入错误!");
                        indexYN = 1;
                    }
                    //4.如果0到上一个运算符之间有一个“.”的话,则后一位只能是“0123456789+-*/.^)”中的一个
                    if (is == 1 && "0123456789+-*/.^)".indexOf(str.charAt(i + 1)) == -1){
                        text.setText("输入错误!");
                        indexYN = 1;
                    }
                    if (is > 1){
                        text.setText("输入错误!");
                        indexYN = 1;
                    }

                }
                //7."123456789"后面只能是“0123456789+-*/.!^)”中的一个
                if ("123456789".indexOf(str.charAt(i)) >= 0 && "0123456789+-*/.!^)".indexOf(str.charAt(i + 1)) == -1){
                    text.setText("输入错误!");
                    indexYN = 1;
                }
                //8."("后面只能是“0123456789locstg()ep”中的一个
                if (str.charAt(i) == '(' && "0123456789locstg()ep".indexOf(str.charAt(i + 1)) == -1){
                    text.setText("输入错误!");
                    indexYN = 1;
                }
                //9.")"后面只能是“+-*/!^)”中的一个
                if (str.charAt(i) == ')' && "+-*/!^)".indexOf(str.charAt(i + 1)) == -1){
                    text.setText("输入错误!");
                    indexYN = 1;
                }
                //10.最后一位字符只能是“0123456789!)ep”中的一个
                if ("0123456789!)ep".indexOf(str.charAt(str.length() - 1)) == -1){
                    text.setText("输入错误!");
                    indexYN = 1;
                }
                //12.不能有多个“.”
                if (i > 2 && str.charAt(i) == '.'){
                    int n = i - 1;
                    int is = 0;
                    while (n > 0){
                        if ("(+-*/^glosct".indexOf(str.charAt(n)) >= 0){
                            break;
                        }
                        if (str.charAt(n) == '.'){
                            is++;
                        }
                        n--;
                    }
                    if (is > 0){
                        text.setText("输入错误!");
                        indexYN = 1;
                    }
                }
                //13."ep"后面只能是“+-*/^)”中的一个
                if ("ep".indexOf(str.charAt(i)) >= 0 && "+-*/^)".indexOf(str.charAt(i + 1)) == -1){
                    text.setText("输入错误!");
                    indexYN = 1;
                }
            }
        }
    }
}

border.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
    <solid android:color="#fff" />
<!--    //设置该控件的背景颜色-->
<!--    //设置边距-->
    <padding
        android:bottom="10dp"
        android:left="10dp"
        android:right="10dp"
        android:top="10dp" />

<!--    //控制边界线颜色和笔触大小-->
    <stroke
        android:width="1dp"
        android:color="#CdCdCd" />
<!--    //控制界面颜色渐变(你这个用不到)-->
    <gradient
        android:startColor="#E9E9E9"
        android:endColor="#FFFFFF"
        android:type="linear"
        android:angle="90"/>
<!--    //控制圆角大小-->
    <corners android:radius="2dp" />
<!--    //如果需要制定每个角度大小-->
    <corners
        android:topRightRadius="2dp"
        android:bottomRightRadius="2dp"
        android:topLeftRadius="2dp"
        android:bottomLeftRadius="2dp"/>
</shape>

  • 6
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值