IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 树莓派提升计划 Android应用科学计算器开发之中缀表达式计算 -> 正文阅读

[移动开发]树莓派提升计划 Android应用科学计算器开发之中缀表达式计算

2021SC@SDUSC

? ? ? ? 这篇研究BaseCalculator类中对中缀表达式的计算

? ? ? ? 使用的是基于堆栈的算法,有一个元素类用于表示后缀表达式中的每一个元素

private class Ele {
        public boolean isNum;
        public double o;
        public char op;
        public Ele(double o,boolean isNum){
            this.isNum=isNum;
            this.o=o;
        }

        public Ele(char op,boolean isNum) {
            this.isNum = isNum;
            this.op = op;
        }
    }

用于进行后缀表达式计算。

? ? ? ? 判断是否是数字

private boolean isNum(char c){
        return (c-'0'>=0&&c-'0'<=9)||c=='.';
    }

? ? ? ? operate方法提供简单的四则和E运算

private double operate(double a, char oper, double b) {
        switch (oper) {
            case '+':
                return a + b;
            case '-':
                return a - b;
            case '×':
                return a * b;
            case '/':
                if (b == 0) {
                    return Double.MAX_VALUE; //处理异常
                }
                return a / b;
            case 'E':
                return Double.parseDouble(String.valueOf(a+"E"+(int)b));
            default:
                return 0;
        }
    }

? ? ? ? 接下来就是关键的运算了

????????先初始化一个队列和数字栈,字符栈

Stack<Character> operStack = new Stack<>();
Queue<Ele> eleQueue = new LinkedList<>();
Stack<Double> numStack = new Stack<>();

? ? ? ? 中缀表达式转后缀表达式

  1. 初始化两个栈:运算符栈s1和储存后缀表达式的队列s2 从左至右扫描中缀表达式; 遇到操作数时,将其压入s2
  2. 遇到运算符时,比较其与s1栈顶运算符的优先级: 如果s1为空,或栈顶运算符为左括号“(”,则直接将此运算符入栈;
  3. 否则,若优先级比栈顶运算符的高,也将运算符压入s1(注意转换为前缀表达式时是优先级较高或相同,而这里则不包括相同的情况);
  4. 否则,将s1栈顶的运算符弹出并压入到s2中,再次转到(4-1)s1中新的栈顶运算符相比较; 遇到括号时:
  5. 如果是左括号“(”,则直接压入s1
  6. 如果是右括号“)”,则依次弹出s1栈顶的运算符,并压入s2,直到遇到左括号为止,此时将这一对括号丢弃;
  7. 重复步骤25,直到表达式的最右边; s1中剩余的运算符依次弹出并压入s2
  8. 依次弹出s2中的元素并输出,结果的逆序即为中缀表达式对应的后缀表达式(转换为前缀表达式时不用逆序)
int firstIndex = 0;
            int i=0;
            while (i < math.length()) {
                char charOfMath = math.charAt(i);
                if (charOfMath == '(') {
                    operStack.push(charOfMath);
                    i++;
                } else if (charOfMath == ')') {
                    while (operStack.peek() != '(') {
                        eleQueue.offer(new Ele(operStack.pop(), false));
                    }
                    operStack.pop();
                    i++;
                }else if(isNum(charOfMath)){
                    firstIndex=i;
                    while (++i<math.length()&&isNum(math.charAt(i)));
                    double num;
                    try {
                        num = Double.parseDouble(math.substring(firstIndex, i));
                    } catch (NumberFormatException e) {
                        return Double.MAX_VALUE;
                    }
                    eleQueue.offer(new Ele(num,true));
                }else{
                    //说明-是单目运算符
                    if (charOfMath == '-') {
                        if (i == 0) {
                            firstIndex=0;
                            while (++i<math.length()&&isNum(math.charAt(i)));
                            double num;
                            try {
                                num = Double.parseDouble(math.substring(firstIndex, i));
                            } catch (NumberFormatException e) {
                                return Double.MAX_VALUE;
                            }
                            eleQueue.offer(new Ele(num,true));
                            continue;
                        } else if (math.charAt(i - 1)=='(') {
                            //表示这是一个单目运算符
                            firstIndex=i;
                            while (++i<math.length()&&isNum(math.charAt(i)));
                            double num;
                            try {
                                num = Double.parseDouble(math.substring(firstIndex, i));
                            } catch (NumberFormatException e) {
                                return Double.MAX_VALUE;
                            }
                            eleQueue.offer(new Ele(num,true));
                            continue;
                        }


                    }
                    while (operStack.size() >= 0) {
                        if (operStack.size() == 0 || operStack.peek() == '(') {
                            operStack.push(charOfMath);
                            break;
                        } else {
                            if (operMap.get(operStack.peek()) < operMap.get(charOfMath)) {
                                operStack.push(charOfMath);
                                break;
                            } else {
                                eleQueue.offer(new Ele(operStack.pop(), false));
                            }
                        }
                    }
                    i++;
                }
            }

            while (operStack.size()>0){
                eleQueue.offer(new Ele(operStack.pop(),false));
            }

? ? ? ? 最后检查后缀表达式进行计算

? ? ? ? 从左到右扫描后缀表达式,如果是操作数,就压入操作数栈s3,如果是操作符,就连续弹出两个操作数(注意:后弹出的为第一操作数,先弹出的为第二操作数),然后进行操作符的操作,将新生成的操作数压入栈中,反复直到后缀表达式扫面完毕,栈s3中只存在一个数,就是最终结果。

while (eleQueue.size() > 0) {
                if (eleQueue.element().isNum) {
                    numStack.push(eleQueue.poll().o);
                } else {
                    char op = eleQueue.poll().op;
                    double second= numStack.pop();
                    double first = numStack.pop();
                    numStack.push(operate(first, op, second));
                }
            }
            return numStack.peek();

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-10-11 17:38:03  更:2021-10-11 17:39:38 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 23:29:07-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码