• [Android]使用Stack实现简易计算器


    前言

    花了点时间帮朋友做了一个计算器,以后可能还用得着,留下来存个档。

    声明
      欢迎转载,但请保留文章原始出处:) 
        博客园:http://www.cnblogs.com
        农民伯伯: http://over140.cnblogs.com

    正文

        private TextView mNumberText;
        /** 格式化数据 */
        private static final DecimalFormat mFormat = new DecimalFormat(
                "###############.######");
        /** 堆栈 */
        private Stack<String> mMathStack = new Stack<String>();

        /** 操作数 入栈 */
        private void push(char obj) {
            final int size = mMathStack.size();
            // 清除
            if ('c' == obj) {
                mMathStack.clear();
                mNumberText.setText("0");
                return;
            }

            // 操作符号
            if ('+' == obj || '-' == obj || '*' == obj || '/' == obj || '=' == obj) {
                switch (size) {
                case 0:
                    break;
                case 2:
                    if ('=' != obj)
                        mMathStack.set(1, obj + "");// 同时输入两个操作符,后面的操作符替换前面的
                    break;
                case 1:
                    if ('=' != obj)
                        mMathStack.push(obj + "");
                    break;
                case 3:
                    String preResult = mFormat.format(calc());
                    mMathStack.push(preResult);
                    if ('=' != obj)
                        mMathStack.push(obj + "");
                    mNumberText.setText(preResult);
                    break;
                }
                return;
            }

            String str = "";
            int location = 0;
            switch (size) {
            case 0:
                mMathStack.push("");
            case 1:
                str = mMathStack.peek();
                break;
            case 2:
                mMathStack.push("");
            case 3:
                location = 2;
                str = mMathStack.peek();
                break;
            }

            int len = str.length();
            if ('d' == obj) {
                // 删除
                if (len > 1)
                    str = str.substring(0, len - 1);
                else if (len == 1)
                    str = "0";
            } else if ('f' == obj) {
                if ("0".equals(str) || len == 0) {
                    return;
                } else if (str.charAt(0) == '-') {
                    str = str.replace('-', ' ').trim();
                } else {
                    str = '-' + str;
                }
            } else {
                if ('.' == obj) {
                    if (str.indexOf(".") > 0)
                        return;
                } else if ('0' == obj) {
                    if (str.length() == 0 || str.equals("0"))
                        return;
                }
                str += obj;
            }
            if ('.' != obj)
                str = mFormat.format(parseDouble(str));
            mMathStack.set(location, str);
            mNumberText.setText(str);
        }

        private double calc() {
            double result = 0.0D;
            if (mMathStack.size() == 3) {
                double right = parseDouble(mMathStack.pop());
                String oper = mMathStack.pop();
                double left = parseDouble(mMathStack.pop());
                if ("+".equals(oper)) {
                    result = left + right;
                } else if ("-".equals(oper)) {
                    result = left - right;
                } else if ("*".equals(oper)) {
                    result = left * right;
                } else if ("/".equals(oper)) {
                    if (right != 0.0D)
                        result = left / right;
                }
            }
            return result;
        }

        /** 解析文本数据 */
        private double parseDouble(String str) {
            try {
                return Double.parseDouble(str);
            } catch (NumberFormatException e) {
                return 0.0D;
            }
        }

        /** 点击事件 */
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
            case R.id.btnDivi:// 除
                push('/');
                break;
            case R.id.btnMult:// 乘
                push('*');
                break;
            case R.id.btnMinus:// 减
                push('-');
                break;
            case R.id.btnPlus:// 加
                push('+');
                break;
            case R.id.btnClear:// C
                push('c');
                break;
            case R.id.btn0:
                push('0');
                break;
            case R.id.btn1:
                push('1');
                break;
            case R.id.btn2:
                push('2');
                break;
            case R.id.btn3:
                push('3');
                break;
            case R.id.btn4:
                push('4');
                break;
            case R.id.btn5:
                push('5');
                break;
            case R.id.btn6:
                push('6');
                break;
            case R.id.btn7:
                push('7');
                break;
            case R.id.btn8:
                push('8');
                break;
            case R.id.btn9:
                push('9');
                break;
            case R.id.btnDot:
                push('.');
                break;
            case R.id.btnEqual:// =
                push('=');
                break;
            case R.id.btnPM:// 符号,正负数
                push('f');
                break;
            case R.id.btnDel:// <- delete
                push('d');
                break;
            }
        }

    代码说明:

    a). R.id这些全是界面上的按钮, 分别代表加减乘除、0-9等。

    b). 基本原理:利用堆栈模型,一个操作数 + 一个操作符 + 一个操作数 完成一次运算,清空栈,把结果压入栈底。

    c). 最大支持小数点前15位和后6位,大家可以调整一下,只是注意不要溢出了。

    d). UI和代码就不提供下载了,需要的也可以简单的封装一下成一个工具类。

    结束

    堆栈模型也很好扩展支持其他的运算符,对于简单运算实现起来很方便,简单测试了一下没有问题,有问题欢迎指正  :)

  • 相关阅读:
    Product of Array Except Self
    如果裸写一个goroutine pool
    fasthttp 的 goroutine pool 实现探究
    golang实现权重轮询调度算法
    golang学习资料
    获取本机ip
    dnscache --源码笔记
    xsrftoken--源码笔记
    forwardport--源码笔记--注释
    golang 通过exec Command启动的进程如何关闭的解决办法 以及隐藏黑色窗口
  • 原文地址:https://www.cnblogs.com/over140/p/2579226.html
Copyright © 2020-2023  润新知