逆波兰式

PHP实现逆波兰式

╄→гoц情女王★ 提交于 2020-03-02 15:25:52
近期一个小项目需要用到公式运算, 所以就进行一些了解,以下内容均属于个人经验。 在PHP中实现公式表达式四则运算大概有两种方法: 1)使用系统函数eval 2)将表达式转换成逆波兰表达式进行计算。 <?php //使用系统函数eval $str = 'L*((k-J)-(C+k))/M'; $param = array('L' => 0.5, 'k' => 2, 'J' => 1, 'C' => 6, 'M' => 4); $str2 = ''; for($i = 0; $i < strlen($str); $i++) { $tmp = substr($str, $i, 1); if (array_key_exists($tmp, $param)) { $str2 .= $param[$tmp]; } else { $str2 .= $tmp; } } eval("\$str = $str2;"); printf('%5.2d', $str); /*End of php*/ <?php /** * math_rpn * * 实现逆波兰式算法 * * @author sparkHuang 260558820@qq.com * @version RPN 1.0.0 * */ class math_rpn { //初始的计算表达式 private $_expression = ''; /

php简单实现算术表达式转换成逆波兰式,并求解

旧街凉风 提交于 2020-02-29 13:27:36
最近一直在学习C/C++,可学的都是原理语法之类的,没有实战成绩甚是令人不爽。想用C/C++写个计算器一直是我的夙愿,刚敲键盘,就不知可否了,想来想去还是对计算器的算法不是很清楚。由于本人是学php出身,所以先使用php将计算器算法给实现了 一下 ,以便更好的学习C/C++。这个简单的计算器采用的是逆波兰式来做的,仅支持加减乘除四种运算,纯粹个人练习记录一下,还望多多支持。 将算术表达式转换成逆波兰式 建立运算符栈stackOperator用于运算符的存储,压入'@';建立逆波兰式存储栈stackOut,并置空 。 预处理表达式,正、负号前加0(如果一个加号(减号)出现在最前面或左括号后面,则该加号(减号)为正负号) 。 顺序扫描表达式,如果当前字符是数字(优先级为0的符号),则直接 入栈 stackOut ;如果当前字符为运算符或括号(优先级不为0的符号),则判断第4点 。 若当前运算符为'(',直接入栈 stackOperator ; 若为')',出栈( stackOperator )并顺序输出运算符直到遇到第一个'(',遇到的第一个'(' 出栈 ( stackOperator ) 但不输出; 若为四则运算符,比较栈顶元素与当前元素的优先级: 如果栈顶元素运算符优先级 >= 当前元素的优先级, 出栈并顺序输出运算符直到栈顶元素优先级<当前元素优先级,然后将当前元素入栈 (

逆波兰式的学习、运用(附带C++写的一个整数的计算器)

旧城冷巷雨未停 提交于 2020-02-29 13:22:09
我们今天普遍使用计算器,在初级的计算器中,由于计算机可没有人那么聪明,很难能够准确得判断运算的优先级,所以在写计算机的计算器的时候,我们需要将获得的四则运算的表达式改写为逆波兰式,方便计算机进行运算。 所谓的逆波兰表示法( Reverse Polish notation , RPN, 或者逆波兰记法),这是一种数学表达式方式,在逆波兰记发中,所有操作符置于操作数的后面,因此也被称为后缀表示法。 就像是树的搜索方式,有前序、中序、后序遍历,在一棵树中,我们将操作符放在节点处,将操作数放在叶子处,优先级越高的操作越靠下,我们普通四则运算的表达式就是使用中序遍历得到的式子,而逆波兰式则是通过后序遍历得到的,举个例子:中缀表达式 (a+b)*c-(a+b)/e 的逆波兰式是 ab+c*ab+e/- 。 要使用逆波兰式进行运算,首先我们需要知道如何将一个普通的四则运算表达式转换为一个标准的逆波兰式,在算法书上都有讲的,也已经是一个很成熟,很方便的算法了。 在理解逆波兰式的时候,我们使用了树的中序遍历辅助我们理解,但是在正式使用的时候,大家千万不要想着先将普通的四则表达式生成一棵树,然后再进行后序遍历生成逆波兰式,这是二逼做的事哈。我帮大家找了一个很简洁,很易懂的哈: Step 1 :我们使用两个栈构建逆波兰式,栈 S1 用于临时储存运算符号,运算符在栈内遵循越往栈顶优先级越高的原则;栈 S2

计算逆波兰式

允我心安 提交于 2020-02-28 18:37:00
在程序设计中,可能碰到需要对字符串数学表达式求值的问题,常用的方法是解析表达式,生成二叉树,然后进行计算。编译器就是使用这种方法来解析程序中的表达式的。这种方法实现起来有点难度,需要考虑运算符的优先级,括号的配对,堆栈的使用等等。我们正常情况下看到的数学表达式如果用二叉树遍历的话,恰好是中序遍历,故叫做中序表达式。除此之外,还有前序表达式,后序表达式。如:a+b+c(中序),++abc(前序),ab+c+(后序),如果表达式含有×,/,()等就更复杂了。 后缀表达式也称逆波兰表达式 因其使表达式求值变得轻松,所以被普遍使用。 逆波兰式: 在通常的表达式中,二元运算符总是置于与之相关的两个运算对象之间(如:1+1),所以这种表示法也称为中缀表示。波兰逻辑学家J.Lukasiewicz于1929年提出了另一种表示表达式的方法,称为逆波兰记法,在逆波兰记法中,所有 操作符 置于 操作数 的后面,因此也被称为后缀表示法。示例如下: 中缀表示 逆波兰式 a+b a,b,+ a+(b-c) a,b,c,-,+ a+(b-c)*d a,b,c,-,d,*,+ a+d*(b-c) a,d,b,c,-,*,+ a=1+3 a=1,3 + 逆波兰表达式是一种十分有用的表达式,它将复杂表达式转换为可以依靠简单的操作得到计算结果的表达式。它的优势在于只用两种简单操作

逆波兰式求值

北慕城南 提交于 2020-01-11 06:24:22
逆波兰式求值 第一步、生成中缀表达式 第二步、中缀表达式转换为后缀表达式 第三步、后缀表达式求值 本次实验采用自主设计链式堆栈结构存储数据 LinkedStack存储中缀及后缀表达式 #pragma once #include <string> using namespace std; typedef struct sign { string sign; int level; struct sign * next; }; class LinkedStack { private: struct sign * top; int count; int compare(string str); public: LinkedStack(); ~LinkedStack(); void push(string str); void pop(); string front(); int frontLevel(); bool isEmpty(); void show(); }; #include "LinkedStack.h" #include <iostream> LinkedStack::LinkedStack() { top = NULL; count = 0; } LinkedStack::~LinkedStack() { } void LinkedStack::push(string

逆波兰表达式

不羁岁月 提交于 2020-01-10 10:43:47
本文转载自: https://www.cnblogs.com/wanghetao/archive/2012/04/23/2466580.html 作者:wanghetao 转载请注明该声明。 逆波兰 表达式 表达式一般由操作数(Operand)、运算符(Operator)组成,例如算术表达式中,通常把运算符放在两个操作数的中间, 这称为中缀表达式(Infix Expression),如A+B。 波兰数学家Jan Lukasiewicz提出了另一种数学表示法,它有两种表示形式: 把运算符写在操作数之前,称为波兰表达式(Polish Expression)或前缀表达式(Prefix Expression),如+AB; 把运算符写在操作数之后,称为逆波兰表达式(Reverse Polish Expression)或后缀表达式(Suffix Expression),如AB+; 其中,逆波兰表达式在编译技术中有着普遍的应用。 算法: 一、 将中缀表达式转换成后缀表达式算法: 1、从左至右扫描一中缀表达式。 2、若读取的是操作数,则判断该操作数的类型,并将该操作数存入操作数堆栈 3、若读取的是运算符 (1) 该运算符为左括号"(",则直接存入运算符堆栈。 (2) 该运算符为右括号")",则输出运算符堆栈中的运算符到操作数堆栈,直到遇到左括号为止。 (3) 该运算符为非括号运算符: (a)

【讲古堂】表达式求值

流过昼夜 提交于 2019-12-04 22:05:07
【讲古堂】表达式求值 ( dubenju@126.com 2015/12/27) 什么是表达式 表达式是由数字,操作符,变量,常量等有意义地组合而成并能求得结果的式子。 例如: 32 + ( ( 9 * Celsius ) / 5 ) 4 + 2 * 55 / 2.5 组成表达式的信息种类繁多,这里只讨论数字表达式,即表达式由以下要素构成: 数字、操作符、变量、常量。 数字 不考虑进制的话,通常指十进制数,小数的时候是有小数点的。数字通常是以被操作对象的身分出现在表达式中的,叫做操作数。 操作符 表示对操作数进行哪种操作的符号叫做操作符,被操作的值叫做操作数,对操作数进行操作的过程称为表达式求值。根据操作对象的个数分为一元操作符和二元操作符。 一元操作符,操作只应用于单一操作数。例如:23!-n。 操作应用于两个操作数的叫二元操作符。例如:6*21、29/11、6.9+19.8、21.1-2.8 优先级 相对其他操作符,每个操作符都有一个优先级,优先级高的操作符比优先级低的操作符优先应用。一般的优先级是这样设置的: 分组操作符()具有最高优先级。 一元操作符-+比乘除模的优先级高。 次方乘除模比加减法的高。 操作数的类型变换 类型变换是指操作的过程中操作数的类型发生变化的现象。 比如: 1/3 1.5/0.3 变量与常量 变量是指值可以变化的量。比如x+5中的x。

编译原理――逆波兰式分析程序(C#)

匿名 (未验证) 提交于 2019-12-03 00:05:01
逆波兰式分析程序实验目的与要求 实验内容 本次实验相对于前几次来说较为简单。对输入的算数表达式进行分析,主要是: 遇到操作符和操作数时的处理方法,以及最后的逆波兰式计算这三部分。 实验步骤 1.分析出完整的运算数或者运算符(参考词法分析)。0代表数字,1代表运算符 Tuple为元组数据类型。 static Tuple < int , string , string > ReadObject ( string inputString ) 2.遇到操作符时的栈操作 static void InsertOp ( string op ) 若取出的字符是运算符,则将该运算符与S1栈栈顶元素比较, 如果该运算符优先级(不包括括号运算符)大于S1栈栈顶运算符优先级,则将该运算符进S1栈 否则,将S1栈的栈顶运算符弹出,送入S2栈中,直至S1栈栈顶运算符低于(不包括等于)该运算符优先级,最后将该运算符送入S1栈。 若取出的字符是“(”,则直接送入S1栈顶。 若取出的字符是“)”,则将距离S1栈栈顶最近的“(”之间的运算符,逐个出栈,依次送入S2栈,此时抛弃“(”。 主要字段: static Stack numStack = new Stack();//遇到操作数直接压入 numStack static Stack opStack = new Stack();//遇到操作符进行分析选择后