逆波兰表达式

逆波兰表达式又叫做后缀表达式。在通常的表达式中,二元运算符总是置于与之相关的两个运算对象之间,这种表示法也称为中缀表示。波兰逻辑学家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,-,*,+

1、将一个中序表达式转化成为逆波兰表达式

构造两个栈S1,S2,S1用来存放表达式,S2用来暂时存放运算符,最后完成后,该栈是清空的。

(1)如果遇到的是数字,直接进栈S1

(2)如果遇到的是左括号,进栈S2

(3)如果遇到的是右括号,将S2中的运算符全部出栈压入S1中,注意括号不压入

(4)如果遇到的运算符

1.如果此时栈S2为空,则直接将运算符加入到栈S2中;

2.如果此时栈S2不为空,当前运算符的优先级大于等于栈顶运算符的优先级,那么直接入栈S2;

3.如果此时栈S2不为空,当前运算符的优先级小于栈顶运算符的优先级,则将栈顶运算符一直出栈压入到栈S1中,  直到栈为空或者遇到一个运算符的优先级小于等于当前遍历的运算符的优先级,然后将该运算符压入到栈S2中。

(5)遍历完整个中序表达式之后,如果栈S2中仍然存在运算符,那么将这些运算符依次出栈压入到栈S1中,直到栈为空。

2、利用逆波兰表达式求值

维护一个结果栈S3,该栈最后存放的是表达式的值。从左至右的遍历栈S1

(1)如果遇到的是数字,直接将数字压入到S3中

(2)如果遇到的是单目运算符,取S3栈顶的一个元素进行运算之后,将结果压入到栈S3中

(3)如果遇到的是双目运算符,取S3栈顶的两个元素,首先出栈的在左,后出栈的在右进行双目运算符的计算,将结果压入到S3中

遍历完整个栈S1,最后S3中的值就是逆波兰表达式的值。

栈实现表达式计算【数据结构】

思路:

所包含的运算符有‘+’,‘-’,‘*’,‘/’,‘(’,‘)’。

(1)建立两个栈,一个用来存储操作数,另一个用来存储运算符, 开始时在运算符栈中先压入‘/0’,一个表达式的结束符。

(2)然后从左至右依次读取表达式中的各个符号(操作数或者运算符);

(3)如果读到的是操作数直接存入操作数栈;

(4)如果读到的是运算符,则作进一步判断:

若读到的是‘/0’结束符,而且此时运算符栈的栈顶元素也是‘/0’结束符,则运算结束,输出操作数栈中的元素即为最后结果。

若读到的是‘(’或者读到的运算符的优先级比目前的运算符栈中的栈顶元素的优先级高,则将运算符直接存入运算符栈,继续读表达式中的下一个符号,重复步骤(3)和(4);

若读到的是‘)’,而且此时运算符栈的栈顶元素是‘(’结束符,则将运算符栈中的栈顶元素退出来,继续读表达式中的下一个符号,重复步骤(3)和(4);

若读到的运算符的优先级等于或小于之前的运算符的优先级,则从操作数中退出2个,从运算符中退出一个进行运算,将运算结果存入操作数栈;再把之前读到的运算符与目前的运算符栈顶比较,重复步骤(4)(即现在不读下一个元素);

/*
输入:
9+(3-1)*3+10/2 输出
20 注意:其实注释的地方可以用来调试,本人主要根据大话数据结构的思路写出来的
如果有什么地方错了,多谢提出。
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
struct stack{
char data[101];
int top;
}; struct stack2{
int data1[101];
int top;
}; struct stack tak;
struct stack2 tak2; bool jia(char s){
if(s=='+' || s=='-')
return true;
else
return false;
}
bool ch(char s){
if(s=='*' || s=='/')
return true;
else
return false;
}
int number(int y, int x, char s){
if(s=='+')
return x + y;
if(s=='-')
return x - y;
if(s=='*')
return x * y;
if(s=='/' )
return x / y;
} int main(){
char s1[20]; scanf("%s",&s1);
getchar(); tak.top = 0;
tak2.top = 0; //中缀表达式转化为后缀表达式
for(int i=0;i<strlen(s1);i++){ if(s1[i]>='0' && s1[i]<='9'){
int tep = s1[i]-'0'; while(s1[i+1]>='0' && s1[i+1]<='9'){
tep *= 10;
i++;
tep += s1[i]-'0';
}
// printf("%d ",tep); tak2.top++;
tak2.data1[tak2.top] = tep; }else{
if(tak.top==0 || tak.data[tak.top]=='('){
tak.top++;
tak.data[tak.top] = s1[i];
}else{
char temp = tak.data[tak.top]; if( jia(temp) && (ch(s1[i]) || jia(s1[i]) || s1[i]=='(') ){
tak.top++;
tak.data[tak.top] = s1[i];
}else if(ch(temp) && (ch(s1[i]) || s1[i]=='(')){
tak.top++;
tak.data[tak.top] = s1[i];
}else if(s1[i]==')'){ while(tak.top>0){ if(tak.data[tak.top]=='('){
tak.top--;
break;
}
// printf("%c ",tak.data[tak.top]); int t1 = tak2.data1[tak2.top];
tak2.top--;
int t2 = tak2.data1[tak2.top];
int t3 = number(t1,t2,tak.data[tak.top]); tak2.data1[tak2.top] = t3; tak.top--;
} }else if(ch(temp) && jia(s1[i])){
while(tak.top>0){
if(tak.data[tak.top]=='('){
break;
}
// printf("%c ",tak.data[tak.top]); int t1 = tak2.data1[tak2.top];
tak2.top--;
int t2 = tak2.data1[tak2.top];
int t3 = number(t1,t2,tak.data[tak.top]);
tak2.data1[tak2.top] = t3; tak.top--;
}
tak.top++;
tak.data[tak.top] = s1[i];
}
}
}
} while(tak.top>0){
// printf("%c ",tk.data[tak.top]); int t1 = tak2.data1[tak2.top];
tak2.top--;
int t2 = tak2.data1[tak2.top];
int t3 = number(t1,t2,tak.data[tak.top]);
tak2.data1[tak2.top] = t3;
// cout<<" t3 = "<<t3<<endl; tak.top--;
} printf("%d",tak2.data1[tak2.top]); return 0;
}

逆波兰表达式[栈 C 语言 实现]的更多相关文章

  1. LeetCode150_Evaluate Reverse Polish Notation评估逆波兰表达式(栈相关问题)

    题目: Evaluate the value of an arithmetic expression in Reverse Polish Notation. Valid operators are+, ...

  2. 关于利用STL栈求解四则中缀表达式以及中缀表达式转逆波兰表达式和逆波兰表达式的求解

    今天总结一下栈的一个重要应用---四则数学表达式的求解 数学表达式的求解是栈的一个重要的应用,在计算机的应用中 如果求解一个四则运算表达式,我们可能会直接写一个程序例如什么printf("% ...

  3. leetcode-简单-栈-逆波兰表达式

    根据逆波兰表示法,求表达式的值. 有效的运算符包括 +, -, *, / .每个运算对象可以是整数,也可以是另一个逆波兰表达式. 说明:  整数除法只保留整数部分. 给定逆波兰表达式总是有效的.换句话 ...

  4. 150. Evaluate Reverse Polish Notation逆波兰表达式

    [抄题]: Evaluate the value of an arithmetic expression in Reverse Polish Notation. Valid operators are ...

  5. [LeetCode] Evaluate Reverse Polish Notation 计算逆波兰表达式

    Evaluate the value of an arithmetic expression in Reverse Polish Notation. Valid operators are +, -, ...

  6. noi1696 逆波兰表达式

    1696:逆波兰表达式 http://noi.openjudge.cn/ch0303/1696/ 总时间限制:  1000ms 内存限制:  65536kB 描述 逆波兰表达式是一种把运算符前置的算术 ...

  7. codevs5164 逆波兰表达式

    题目描述 Description 逆波兰表达式是一种把运算符前置的算术表达式(又叫前缀表达式),例如普通的表达式2 + 3的逆波兰表示法为+ 2 3.逆波兰表达式的优点是运算符之间不必有优先级关系,也 ...

  8. lintcode 中等题:Evaluate Reverse Polish notation逆波兰表达式求值

    题目 逆波兰表达式求值 在逆波兰表达法中,其有效的运算符号包括 +, -, *, / .每个运算对象可以是整数,也可以是另一个逆波兰计数表达. 样例 ["2", "1&q ...

  9. SDIBT2666——逆波兰表达式求值

    逆波兰表达式求值(栈和队列) Description 从键盘上输入一个逆波兰表达式,用伪码写出其求值程序.规定:逆波兰表达式的长度不超过一行,以@符作为输入结束,操作数之间用空格分隔,操作符只可能有+ ...

随机推荐

  1. SpringMVC使用校验validator校验对象属性

    1.pom.xm添加依赖 <dependency> <groupId>javax.validation</groupId> <artifactId>va ...

  2. ECS centos6.8系统下从nginx安装到简单网站上线配置操作的完整记录

    1.准备工作 1.1已购买阿里云云服务器ECS 1.2域名已购买并解析成功 1.3安装有远程链接工具Xshell和文件传输工具Xftf,并链接上ECS实例 2.安装nginx(在Xshell操作) 2 ...

  3. Matplotlib中中文不显示问题

    我们在使用jupter进行数据分析的时候,会接触到Matplotlib这个库,它是用来进行可视化数据分析的,在一个图中,我们常常会加入一些中文来进行说明.当我们加入中文的时候会出现下图所示的样子: 可 ...

  4. 【微信开发】微信开发模式 api 接口文档简介

    微信公众平台分为订阅号和服务号,服务号提供9大接口,需要通过微信认证后才能使用这些接口.认证费用300元.下面是接口的大致介绍: 1. 语音识别:通过语音识别接口,用户发送的语音,将会同时给出语音识别 ...

  5. oracle系列(四)PL/SQL

    过程,函数,触发器是PL/SQL编写的,存储在oracle中的.PL/SQL是非常强大的数据库过程语言. PL/SQL优点:性能,模块化,网络传输量,安全性缺点:移植性不好 简单分类:块:过程,函数, ...

  6. ABI是什么? Swift ABI稳定有什么好处?

    ABI是什么? 在软件开发中, 应用程序机器二元码界面(Application Binary Interface 简称ABI)指两个程序模块间的接口; 通常其中一个车还给你徐模块会是库或者操作系统提供 ...

  7. C++分享笔记:扑克牌的洗牌发牌游戏设计

    笔者在大学二年级期间,做过的一次C++程序设计:扑克牌的洗牌发牌游戏.具体内容是:除去大王和小王,将52张扑克牌洗牌,并发出5张牌.然后判断这5张牌中有几张相同大小的牌,是否是一条链,有几个同花等. ...

  8. mysql复制表结构和数据

    1.复制表结构: create table newName like oldName;//可以复制所有结构. 或者: create table newName select * from oldNam ...

  9. linux中删除文件内空白行的几种方法。

    linux中删除文件内空白行的几种方法 有时你可能需要在 Linux 中删除某个文件中的空行.如果是的,你可以使用下面方法中的其中一个.有很多方法可以做到,但我在这里只是列举一些简单的方法. 你可能已 ...

  10. 四、分离分层的 platform驱动

    学习目标: 学习实现platform机制的分层分离,并基于platform机制,编写led设备和驱动程序: 一.分离分层 输入子系统.usb设备比驱动以及platform类型的驱动等都体现出分离分层机 ...