千家信息网

Android中如何实现一个简易计算器功能

发表于:2025-01-24 作者:千家信息网编辑
千家信息网最后更新 2025年01月24日,这篇文章主要介绍"Android中如何实现一个简易计算器功能",在日常操作中,相信很多人在Android中如何实现一个简易计算器功能问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对
千家信息网最后更新 2025年01月24日Android中如何实现一个简易计算器功能

这篇文章主要介绍"Android中如何实现一个简易计算器功能",在日常操作中,相信很多人在Android中如何实现一个简易计算器功能问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"Android中如何实现一个简易计算器功能"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

界面布局

1.界面布局分三大块:公式文本区、结果文本区、按钮区。
2.通过点击按钮录入数学公式,实时展示在公式文本区。
3.点击等号,计算结果展示在结果文本区。
4.另外还有清空数据和删除一个字符功能。

计算逻辑

1.将中缀表达式转换为后缀表达式
2.计算后缀表达式得出结果

其他说明

栈数据结构简单说明:

1.栈数据结构像弹夹一样,先压进去的子弹后打出来,后压进去的子弹先打出来
2.入栈:将元素放进栈里,并改变栈顶指针
3.出栈:将元素从栈里拿出来,并改变栈顶指针
4.查看栈顶,取得栈顶元素,但不改变栈顶指针

中缀表达式转后缀表达式简单说明

1.如果是数字,直接放进后缀表达式里。

2.如果是左括号,入栈。

3.如果是右括号,依次出栈(放到后缀表达式里),直到遇到左括号。

4.运算符号:

1).空栈或栈顶是左括号,入栈
2).栈顶符号优先级比当前符号小,入栈
3).栈顶符号优先级大于等于当前符号,依次出栈(放到后缀表达式里),直到遇到不满足条件的元素或栈被掏空。

5.最后如果栈还有符号,依次出栈(放到后缀表达式里)

后缀表达式计算简单说明

1.如果是数字,入栈
2.如果是运算符,将栈顶的两个数字弹出并计算(先出栈的数字放在运算符后面进行计算),再将计算结果入栈。

代码

界面代码

                                                    

后台逻辑

package com.example.calc;import android.os.Bundle;import android.widget.Button;import android.widget.TextView;import androidx.appcompat.app.AppCompatActivity;import com.example.calc.utils.Stack;import java.util.ArrayList;import java.util.Arrays;import java.util.HashMap;import java.util.List;import java.util.Map;public class MainActivity extends AppCompatActivity {    static final String ADD_TEXT = "+";    static final String SUBSTRACTION_TEXT = "-";    static final String MULTIPLICATION_TEXT = "×";    static final String DIVISION_TEXT = "÷";    static final String LEFT_BRACKET_TEXT = "(";    static final String RIGHT_BRACKET_TEXT = ")";    //符号集合    static final List SYMBOLS = Arrays.asList(ADD_TEXT, SUBSTRACTION_TEXT, MULTIPLICATION_TEXT, DIVISION_TEXT, LEFT_BRACKET_TEXT, RIGHT_BRACKET_TEXT);    //符号优先级    static final Map SYMBOL_PRIORITY_LEVEL = new HashMap(4) {{        put(ADD_TEXT, 1);        put(SUBSTRACTION_TEXT, 1);        put(MULTIPLICATION_TEXT, 2);        put(DIVISION_TEXT, 2);    }};    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        initView();    }    private void initView() {        TextView expTextView = findViewById(R.id.the_expression);        TextView resultTextView = findViewById(R.id.the_result);        //数字与运算符按钮        int[] ids = {R.id.zero, R.id.one, R.id.two, R.id.three, R.id.four, R.id.five, R.id.six, R.id.seven, R.id.eight, R.id.nine, R.id.point, R.id.add, R.id.substraction, R.id.mulitipliction, R.id.division, R.id.left_bracket, R.id.right_bracket};        for (int id : ids) {            findViewById(id).setOnClickListener((v) -> {                String newText = expTextView.getText().toString() + ((Button) v).getText().toString();                expTextView.setText(newText);            });        }        //删除一个字符        findViewById(R.id.delete).setOnClickListener((v) -> {            CharSequence text = expTextView.getText();            if (text != null && text.length() > 0) {                if (text.length() == 1) {                    expTextView.setText(null);                } else {                    expTextView.setText(text.subSequence(0, text.length() - 1));                }            }        });        //清理        findViewById(R.id.clear).setOnClickListener((v) -> {            expTextView.setText(null);            resultTextView.setText(null);        });        //等于        findViewById(R.id.equal).setOnClickListener((v) -> {            List infix = getInfix(expTextView.getText().toString());            List suffix = infixToSuffix(infix);            Double result1 = getResult(suffix);            String result = String.valueOf(result1);            if (result.contains(".") && result.split("\\.")[1].replace("0", "").length() == 0) {                result = result.split("\\.")[0];            }            resultTextView.setText(result);        });    }    //字符串转中缀表达式    private List getInfix(String exp) {        List texts = new ArrayList<>();        char[] chars = exp.toCharArray();        StringBuilder sText = new StringBuilder();        for (char c : chars) {            String text = String.valueOf(c);            if (SYMBOLS.contains(text)) {                if (sText.length() > 0) {                    texts.add(sText.toString());                    sText.delete(0, sText.length());                }                texts.add(text);            } else {                sText.append(text);            }        }        if (sText.length() > 0) {            texts.add(sText.toString());            sText.delete(0, sText.length());        }        return texts;    }    //中缀表达式转后缀表达式    private List infixToSuffix(List infix) {        List sufText = new ArrayList<>();        Stack stack = new Stack<>(infix.size());        for (String text : infix) {            if (!SYMBOLS.contains(text)) {                //数值,直接放到后缀表达式                sufText.add(text);            } else if (LEFT_BRACKET_TEXT.equals(text)) {                //左括号,直接入栈                stack.push(text);            } else if (RIGHT_BRACKET_TEXT.equals(text)) {                //右括号,依次取出栈顶元素放到后缀表达式,直到遇到左括号                while (!stack.isEmpty()) {                    String pop = stack.pop();                    if (!LEFT_BRACKET_TEXT.equals(pop)) {                        sufText.add(pop);                    } else {                        break;                    }                }            } else {                //其他符号(+-*/)                buildSuffix(text, sufText, stack);            }        }        //取出剩余栈内数据放到后缀表达式        while (!stack.isEmpty()) {            sufText.add(stack.pop());        }        return sufText;    }    //后缀表达式求结果    private Double getResult(List suffix) {        Stack stack = new Stack<>(suffix.size());        for (String text : suffix) {            switch (text) {                case SUBSTRACTION_TEXT: {                    Double pop1 = stack.pop();                    Double pop2 = stack.pop();                    stack.push(pop2 - pop1);                    break;                }                case ADD_TEXT: {                    Double pop1 = stack.pop();                    Double pop2 = stack.pop();                    stack.push(pop1 + pop2);                    break;                }                case DIVISION_TEXT: {                    Double pop1 = stack.pop();                    Double pop2 = stack.pop();                    stack.push(pop2 / pop1);                    break;                }                case MULTIPLICATION_TEXT: {                    Double pop1 = stack.pop();                    Double pop2 = stack.pop();                    stack.push(pop1 * pop2);                    break;                }                default:                    stack.push(Double.valueOf(text));                    break;            }        }        return stack.pop();    }    private void buildSuffix(String symbol, List suffix, Stack stack) {        if (stack.isEmpty()) {            //是空栈符号直接入栈            stack.push(symbol);        } else {            //栈顶查看            String peek = stack.peek();            //栈顶是左括号符号或当前符号优先级大于栈顶符号直接入栈            if (LEFT_BRACKET_TEXT.equals(peek) || isGreaterThanLevel(symbol, peek)) {                stack.push(symbol);            } else {                //栈顶不是左括号,依次取出比当前符号优先级小或优先级相同的符号放到后缀表达式                while (!stack.isEmpty()) {                    if (isLessThanOrEquals(symbol, stack.peek())) {                        suffix.add(stack.pop());                    } else {                        //遇到不符合条件的栈顶数据,直接退出                        break;                    }                }                //取完数据后,将当前符号入栈                stack.push(symbol);            }        }    }    private boolean isGreaterThanLevel(String symbol, String peek) {        Integer symbolLevel = SYMBOL_PRIORITY_LEVEL.get(symbol);        Integer peekLevel = SYMBOL_PRIORITY_LEVEL.get(peek);        return symbolLevel != null && peekLevel != null && symbolLevel > peekLevel;    }    private boolean isLessThanOrEquals(String symbol, String peek) {        Integer symbolLevel = SYMBOL_PRIORITY_LEVEL.get(symbol);        Integer peekLevel = SYMBOL_PRIORITY_LEVEL.get(peek);        return symbolLevel != null && peekLevel != null && symbolLevel <= peekLevel;    }}

栈数据结构

package com.example.calc.utils;public class Stack {    private int size;    private Object[] elements;    private int top = -1;    public Stack(int size) {        this.size = size;        elements = new Object[size];    }    //压栈    public void push(T element) {        if (top != size - 1) {            elements[top + 1] = element;            top++;        } else {            throw new RuntimeException("stack is full!");        }    }    //弹栈    public T pop() {        if (top > -1) {            top--;            return (T) elements[top + 1];        } else {            throw new RuntimeException("stack is null!");        }    }    //查看栈顶    public T peek() {        if (top > -1) {            return (T) elements[top];        } else {            return null;        }    }    public boolean isEmpty(){        return top == -1;    }}

到此,关于"Android中如何实现一个简易计算器功能"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

0