中缀表达式

计算器核心解析算法(上)

淺唱寂寞╮ 提交于 2020-03-09 19:32:01
计算机如何读懂四则运算表达式? 9.3 + (3 - -0.11) * 5 后缀表达式 人类习惯的数学表达式叫做中缀表达式 另外,还有一种将运算符放在数字后面的后缀表达式 5 + 3——> 5 3 + 1 + 2 * 3 ——> 1 2 3 * + 9 + (3 - 1) *5 ——> 9 3 1 - 5* + 中缀表达式符合 人类的阅读和思维习惯 后缀表达式符合 计算机的运算方式 ——消除了中缀表达式中的括号 ——同时保留中缀表达式中的运算优先级 解决方案 1.将中缀表达式进行 数字和运算符 的分离 2.将中缀表达式转换为后缀表达式 3.通过后缀表达式计算最终结果 分离算法分析 所要计算的中缀表达式中包含 ——数字和小数点[ 0-9或.] ——符号位[+ 或-] ——运算符[+ - * /] ——括号 [( 或 )] 9.3 + ( 3 - -0.11 ) * 5 思想:以符号作为标志对表达式中的字符逐个访问 ——定义累计变量num(字符串) —— 当前字符exp[i]为数字或小数点时:     累计:num += exp[i] —— 当前字符exp[i]为符号时:    num为运算数,分离并保存      若exp[i]为正负号 :       累计符号位 +和- : num +=exp[i]      若exp[i]为运算符 :       分离并保存 for(int i

将中缀表达式转化成后缀表达式来计算值

假如想象 提交于 2020-02-22 18:04:46
题目很简单,就是给出一个表达式(例如2*(3+5)+6),然后我们得出他的值。 未接触这个方法前,我是用了一种很复杂的方法(爆肝警告) 将中缀表达式(就是我们要求的表达式)转化成后缀表达式来解决就会比较简单。 对于中缀表达式和后缀表达式的概念这里就不说了,只将方法呈现出来。 例如一个中缀表达式:A+(B-C/D)✖E,是如何将其转化成后缀表达式:ABCD/-E✖+的?(忽略乘号的特殊) 直接介绍下方法,对这个中缀表达式依次进行扫描,如果是 数字 ,则直接存入放后缀表达式的数组中;如果是 符号 ,先与存符号的栈顶符号进行比较,若 优先级较大 则进栈,若 小于或等于 则栈顶出栈到后缀表达式的数组,此字符继续与现在的栈顶比较,进行循环操作;如果读到 左括号 ,则左括号直接进栈;如果读到 右括号 ,则符号依次退栈直到遇到左括号,左括号哪项也退栈,但不存入后缀表达式。 对后缀表达式计算就是依次扫描,扫描到符号,则符号前的两个数进行符号运算,直到扫描完。 接下来直接上代码 # include <stdio.h> # include <string.h> # define maxn 1005000 char s [ maxn ] ; //存中缀表达式 char s1 [ maxn ] ; //存后缀表达式的符号 char s2 [ maxn ] ; //存符号的栈 int a [ maxn ]

栈的简单应用之中缀表达式转后缀表达式(C语言实现逆波兰式)

旧时模样 提交于 2020-01-29 01:55:20
一、前言   普通人在书写计算式时会选择中缀表达式,这样符合人脑的认知习惯。可计算机处理时后缀表达式才能使处理速度更快,其原因是利用堆栈结构减少计算机内存访问。同时它也是一个很好锻炼栈这个数据结构的应用的问题。以下是用c语言实现中缀表达式到后缀表达式的转换的代码。本文仅讨论转换,不涉及计算。实际上如果了解了栈是如何在这上面应用,计算和前缀、中缀、后缀的相互计算和转换便简单了许多。对于三只种表达方式的转换,还有的做法是建立二叉树,录入数据,三种不同的遍历方式就是三种表达方式。本文若有错误欢迎指出。 二、代码 #include <stdio.h> int main(void) { int top=-1; char s[25],temp; //栈的大小根据需要更改,或者可以用内存分配来解决 while((temp=getchar())!='\n') { if(temp>='A'&&temp<='Z'||temp>='a'&&temp<='z'||temp>='0'&&temp<='9'||temp=='.') //包含数字表达式和字母表达式,支持小数 printf("%c",temp); else { if(temp=='*'||temp=='/') { while(top>=0&&(s[top]=='*'||s[top]=='/')) //保证栈不会越界 printf("%c",s

Java堆栈的应用2----------中缀表达式转为后缀表达式的计算Java实现

穿精又带淫゛_ 提交于 2020-01-25 09:34:51
1、堆栈-Stack 堆栈(也简称作栈)是一种特殊的线性表,堆栈的数据元素以及数据元素间的逻辑关系和线性表完全相同,其差别是线性表允许在任意位置进行插入和删除操作,而堆栈只允许在固定一端进行插入和删除操作。 堆栈中允许进行插入和删除操作的一端称为栈顶,另一端称为栈底。堆栈的插入和删除操作通常称为进栈或入栈,堆栈的删除操作通常称为出栈或退栈。 Java中已经出了Stack的具体实现类 堆栈的数据集合可以表示为a0,a1,…,an-1,每个数据元素的数据类型可以是任意的类类型。 操作集合  (1)入栈push(obj):把数据元素obj插入堆栈。  (2)出栈pop():出栈, 删除的数据元素由函数返回。  (3)取栈顶数据元素getTop():取堆栈当前栈顶的数据元素并由函数返回。 (4)非空否notEmpty():若堆栈非空则函数返回true,否则函数返回false。 堆栈是各种软件系统中应用最广泛的数据结构之一。括号匹配和表达式计算是编译软件中的基本问题,其软件设计中都需要使用堆栈。 首先来看应用之一: 中缀表达式转为后缀表达式 1、前缀表达式(Prefix Notation)是指将运算符写在前面操作数写在后面的不包含括号的表达式,而且为了纪念其发明者波兰数学家Jan Lukasiewicz所以前缀表达式也 叫做“波兰表达式”。比如- 1 + 2 3 2、后缀表达式

使用JAVA数组实现顺序栈

自作多情 提交于 2020-01-24 08:16:59
1,中缀表达式的定义及为什么要将中缀表达式转换为后缀表达式? 中缀表达式(中缀记法) 中缀表达式是一种通用的算术或逻辑公式表示方法,操作符以中缀形式处于操作数的中间。中缀表达式是人们常用的算术表示方法。 虽然人的大脑很容易理解与分析中缀表达式,但对计算机来说中缀表达式却是很复杂的,因此计算表达式的值时,通常需要先将中缀表达式转换为前缀或后缀表达式,然后再进行求值。对计算机来说,计算前缀或后缀表达式的值要比中缀表达式简单。 比如,计算机计算后缀表达式的过程如下---- 后缀表达式的计算机求值: 从左至右扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(次栈顶元素 op 栈顶元素),并将结果入栈;重复上述过程直到表达式最右端,最后运算得出的值即为表达式的结果。 例如后缀表达式“3 4 + 5 × 6 -”: (1) 从左至右扫描,将3和4压入堆栈; (2) 遇到+运算符,因此弹出4和3(4为栈顶元素,3为次顶元素,注意与前缀表达式做比较),计算出3+4的值,得7,再将7入栈; (3) 将5入栈; (4) 接下来是×运算符,因此弹出5和7,计算出7×5=35,将35入栈; (5) 将6入栈; (6) 最后是-运算符,计算出35-6的值,即29,由此得出最终结果。 2, 中缀表达式转换为后缀表达式算法:

中缀表达式求值

守給你的承諾、 提交于 2020-01-21 09:06:08
所谓 表达式的求值 就是从键盘上输入一个四则运算表达式按下Enter后在屏幕上输出表达式的结果。表达式的求值 在计算机的应用中非常广泛, 例如编译器中对所写的程序表达式的编译等。它 也是数据结构课程中栈这一章节中非常重要的一个算法,通过实现这个算法可以更好的掌握 和理解 栈的相关操作 。 中缀表达式是指运算符在运算数的中间,计算中缀表达式时需要用到两个栈:数字栈和运算符栈。在整个中缀表达式求值的过程中主要涉及到的模块有:栈的相关操作、优先级表的确立、输入的待计算字符串拆分为数字和运算符以及运算处理等。 一) 、整体算法思路 1) 、设立操作数栈和运算符栈,设表达式结束的标志是字符#,运算符栈底初始化为#,约定#运算符的优先级最小(这样做的目的是在当两个#相遇时就可以确定表达式扫描结束了)。 2) 、若当前扫描到的是操作数则果断将此数压栈进操作数栈,如果当前是符号栈则将该操作符和栈顶操作符进行优先级比较如果低于栈顶优先级则将操作符栈顶元素弹出并弹出两个操作数进行运算,运算完毕将结果压入栈中。如果当前符号的优先级高于栈顶优先级则将此运算符入栈。 3) 、循环操作2直到输入的表达式运算结束(运算符栈底的#和输入的表达式的#相遇)此时如若操作数栈中只剩一个数字则表示运算成功,此数就是表达式的结果,如果不止一个数则表示输入的表达式有误。 二) 、优先级表

将中缀表达式转换成后缀表达式

倖福魔咒の 提交于 2020-01-18 12:05:34
我们人脑很容易理解中缀表达式,但是中缀表达式在计算机并不好计算,所有我们要将中缀表达式转换成后缀表达式,因为后缀表达式是很容易计算的。为什么要写一个这样的程序呢?原因是我一开始想写一个计算机,它能够将输入的表达式的值计算出来。一开始觉得这样子的程序应该是很简单的,然后开始动手写,开始写了之后才发现并不是那么简单。后来我知道了后缀表达式,才知道原来要这样子才能将表达式的值计算出来。 言归正传 首先是将中缀表达式转换成后缀表达式的方法: 1、遇到操作数:直接输出(添加到后缀表达式中) 2、栈为空时,遇到运算符,直接入栈 3、遇到左括号:将其入栈 4、遇到右括号:执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出 5、遇到其他运算符:加减乘除:弹出所有优先级大于或者等于该运算符的栈顶元素,然后将该运算符入栈 6、最终将栈中的元素依次出栈,输出 看似很简单,但是写起来真的很头痛。为此我画了好多流程图。我觉得画流程图挺好的,能加深理解。 这次我决定用C 语言。 首先要做一些准备工作。 一、实现堆栈的数据结构,具有以下方法: 1. 初始化堆栈,返回堆栈指针 2. 压入一个元素 3. 弹出一个元素 我所实现的这个堆栈的栈顶元素是空的,它只用于指向堆栈的第一个元素,如果堆栈为空的则它指向NULL。 具体代码: //实现栈的数据结构 typedef struct Node {

逆波兰式求值

北慕城南 提交于 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-11 00:58:41
接上篇 数据结构——栈(中缀表达式转后缀表达式) 这里再做一个前缀表达式的总结: 初始化两个栈:运算符栈S1和储存中间结果的栈S2; 从 右至左 扫描中缀表达式; 遇到操作数时,将其压入S2; 遇到 运算符 时,比较其与S1栈顶运算符的优先级: 4.1 如果 S1为空或栈顶运算符为右括号“)” ,则直接将此运算符入栈; 4.2 否则,若优先级比栈顶运算符的 较高或相等 ,也将运算符压入S1; 4.3 否则,将S1栈顶的运算符弹出并压入到S2中,再次转到(4-1)与S1中新的栈顶运算符相比较; 遇到括号时: 5.1 如果是 右括号“)” ,则直接压入S1; 5.2 如果是左括号“(”,则依次弹出S1栈顶的运算符,并压入S2,直到遇到右括号为止,此时将这一对括号丢弃( 注意栈顶右括号的舍弃 ); 重复步骤(2)至(5),直到表达式的最左边; 将S1中剩余的运算符依次弹出并压入S2; 依次弹出S2中的元素并输出,结果即为中缀表达式对应的前缀表达式。 代码示例:表达式→逆向列表→前缀表达式右→计算结果(操作符优先级获取、计算结果获取位于 上一篇博客 中) 根据表达式获取列表(由于逆向扫描,直接将表达式转成逆向列表) private static List < String > toPrefixExpressionList ( String expresion ) { if (

逆波兰表达式

不羁岁月 提交于 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)