使用E.W.D.Dijkstra设计算法实现算数表达式求值

要求:编程模拟(1+(2+3)*(4*5))的运算过程,重点在于如何解析由括号运算符和数字组成的字符串,并按照正确的顺序完成各种初级运算符的操作。

实现思路:用两个栈(LIFO)结构来实现(一个用于保存运算符,一个用于保存操作数)

  1. 将操作数压如操作数栈
  2. 将操作符压如操作符栈
  3. 忽略左括号
  4. 在遇到右括号时,弹出一个运算符,并弹出所需数量的操作数,并将操作符和操作数的运算结果压到操作数栈

     1 package com.luochuang.demo.stdlib;
     2
     3 public class Evalute {
     4     public static void main(String[] args) {
     5         Stack<String> ops = new Stack<String>();
     6         Stack<Double> vas = new Stack<Double>();
     7         while (!StdIn.isEmpty()) {
     8             //读取字符,如果是运算符则压入栈
     9             String s = StdIn.readString();
    10             if (s.endsWith("(")) {
    11             } else if (s.endsWith("+")) {
    12                 ops.push(s);
    13             } else if (s.endsWith("-")) {
    14                 ops.push(s);
    15             } else if (s.endsWith("*")) {
    16                 ops.push(s);
    17             } else if (s.endsWith("/")) {
    18                 ops.push(s);
    19             } else if (s.endsWith("sqrt")) {
    20                 ops.push(s);
    21             } else if (s.endsWith(")")) {
    22                 // 当遇到右操作数,弹出一个运算符
    23                 String op = ops.pop();
    24                 double v = vas.pop();
    25                 if (op.endsWith("+")) {
    26                     v = vas.pop() + v;
    27                 } else if (op.endsWith("-")) {
    28                     v = vas.pop() - v;
    29                 } else if (op.endsWith("*")) {
    30                     v = vas.pop() * v;
    31                 } else if (op.endsWith("/")) {
    32                     v = vas.pop() / v;
    33                 } else if (op.endsWith("sqrt")) {
    34                     v = Math.sqrt(v);
    35                 }
    36                 vas.push(v);
    37             } else {
    38                 //如果字符既非操作符也不是括号,就将它作为double值压入操作数栈
    39                 vas.push(Double.parseDouble(s));
    40             }
    41         }
    42     }
    43 }

    代码解析:每当算法遇到一个被括号包围并有一个运算符和两个操作数连接的表达式的时候,它都能将运算符和操作数的计算结果压如操作数栈,这样的结果就好像用这个值代替了该子表达式,因此用这个值代替子表达式的结果和原表达式相同。
    在处理完最后一个右括号之后,操作数栈上只有一个值,他就是表达式的值。

    图解:

使用E.W.D.Dijkstra设计算法实现算数表达式求值

时间: 2024-10-29 06:57:42

使用E.W.D.Dijkstra设计算法实现算数表达式求值的相关文章

Dijkstra的双栈算术表达式求值

import java.util.Stack; import java.util.Scanner; public class Evaluate { public static void main(String[] args) { Stack<String> ops=new Stack<String>(); Stack<Double> vals=new Stack<Double>(); Scanner cin=new Scanner(System.in); /

Dijkstra的双栈算术表达式求值算法 C++实现

1 #include<iostream> 2 #include<string> 3 using namespace std; 4 5 template<typename T> 6 class Stack 7 { 8 private: 9 T stack[100]; 10 int i = 0; 11 public: 12 Stack() = default; 13 14 T pop() 15 { 16 if (i == -1) 17 { 18 cout <<

Dijkstra的双栈算术表达式求值算法

1 public static double evaluate(String inStr) { 2 Stack<String> ops = new Stack<String>(); //操作符栈 3 Stack<Double> vals = new Stack<Double>(); //操作数栈 4 char[] arr = inStr.toCharArray(); 5 for(char c : arr){ 6 String s =c+""

栈练习--Dijkstra的双栈算术表达式求值算法

此法还有待完善,比如在做除法运算时未判断除数是否为0,而且也可以加以扩展,比如log.sin.操作符优先级.. 1 public class Evaluate { 2 3 public static void main(String[] args) { 4 String steam = "( 1 + ( 2 + 3 ) * ( 4 * 5 ) ) )"; 5 // String steam = "( ( 1 + sqrt ( 5.0 ) ) / 2.0 )"; 6

【算法#4】表达式求值

最讨厌这种造计算器的题了-- 最近被这种造计算器的题坑了几次,一个还是普及-的题.表达式有很多,但是我们在面对狗屎的中缀表达式的时候有没有一些确定的原则? 有.其中一个就是在操作符入操作符栈之前,操作符栈顶的操作符优先级一定得严格低于该操作符优先级,否则弹出操作符并且对操作数栈的栈顶数进行运算直到栈空或者当前优先级严格大于栈顶操作符优先级.当然,前提是你采用这种求值方法,其他的东西暂不予考虑. 首先,我们遇到操作数时,读入操作数并且将操作数加入操作数栈,当我们读入操作符时,弹出操作符栈栈顶元素直

【算法】E.W.Dijkstra算术表达式求值

算术表达式求值 我们要学习的一个栈的用例同时也是展示泛型的应用的一个经典例子,就是用来计算算术表达式的值,例如 ( 1 + ( ( 2 + 3 ) * ( 4 * 5 ) ) ) 如果将4乘以5,把3加上2,取它们的积然后加上1,就得到了101.但Java系统是如何完成这些运算的呢?不需要研究Java系统的构造细节,我们也可以编写一个Java程序来解决这个问题.它接受一个输入字符串(表达式)并输出表达式的值.为了简化问题,首先来看一下这份明确的递归定义:算术表达式可能是一个数,或者是由一个左括号

算法手记(2)Dijkstra双栈算术表达式求值算法

这两天看到的内容是关于栈和队列,在栈的模块发现了Dijkstra双栈算术表达式求值算法,可以用来实现计算器类型的app. 编程语言系统一般都内置了对算术表达式的处理,但是他们是如何在内部实现的呢?为了了解这个过程,我们可以自行搭建一套简易的算术表达式处理机制,这里就用到栈特性和本篇提到的Dijkstra算法. 概述:     算术表达式可能是一个数.或者是由一个左括号.一个算术表达式.一个运算符.另一个算术表达式和一个右括号组成的表达式.为了简化问题,这里定义的是未省略括号的算术表达式,它明确地

算法-表达式求值

今天在网上看到Dijkstra双栈算术表达式求值算法,可以用来实现计算器类型的app,以前很早的时候知道通过算术栈和数值栈搞定的,这次用OC通过数组实现了预期的效果,编程语言系统一般都内置了对算术表达式的处理,我们可以简易的模仿一下算术表达式处理机制,思想不变,主要是实现方式略有不同.算术表达式可能是一个数.或者是由一个左括号.一个算术表达式.一个运算符.另一个算术表达式和一个右括号组成的表达式.为了简化问题,这里定义的是未省略括号的算术表达式,它明确地说明了所有运算符的操作数,形式如下:(1+

表达式求值算法、rpn、1470、1475、1477、1479

以下为表达式求值系列完整算法,借用C++语言,读者不妨对照下图表达式求值算法实例,仔细推敲. 1 /* 2 DATA:2015 1 30 3 From:13420228 4 */ 5 //测试数据: 6 // 4 7 // (0!+1)*2^(3!+4) - (5! - 67 - (8+9)) 8 // (1+2)*3+4*5 9 // 1.000 + 2 / 4 10 // ((1+2)*5+1)/(4^2)*3 11 #include <iostream> 12 #include <