逆波兰表达式

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

    可以看做一个状态机, 生成的是一个迭代器对象, 可以用来遍历状态机里面的各种状态 创建方式 在函数名前面添加 * , 内部使用 yeild 来标注状态 特性 yield 只能在 generator 中 ...

  2. 使用Redis+java(模仿数据库)实现对象存取和读取

    实现前要引入Redis架包 maven项目 <dependency> <groupId>redis.clients</groupId> <artifactId ...

  3. Oracle 常用脚本

    ORACLE 默认用户名密码 sys/change_on_install SYSDBA 或 SYSOPER 不能以 NORMAL 登录,可作为默认的系统管理员 system/manager SYSDB ...

  4. 更新UI放在主线程的原因

    1.在子线程中是不能进行UI 更新的,而可以立刻更新的原因是:子线程代码执行完毕了,又自动进入到了主线程,这中间的时间非常的短,让我们误以为子线程可以更新UI.如果子线程一直在运行,则无法更新UI,因 ...

  5. 『ACM C++』HDU杭电OJ | 1418 - 抱歉 (拓扑学:多面体欧拉定理引申)

    呕,大一下学期的第一周结束啦,一周过的挺快也挺多出乎意料的事情的~ 随之而来各种各样的任务也来了,嘛毕竟是大学嘛,有点上进心的人多多少少都会接到不少任务的,忙也正常啦~端正心态 开心面对就好啦~ 今天 ...

  6. Linux在线安装jdk8,并配置环境变量

    1.创建相关目录:下载目录.安装目录 下载目录: cd / 2.下载jdk8到目录 下载前先跳转到下载目录,比如希望最后压缩包下载到/home/bak/下, 则先创建bak目录,命令如下: 注意:如果 ...

  7. centos7安装ftp

    1.服务器初始化检查 检查selinux,firewall,iptables是否开启 1.查看selinux的运行状态 [root@zeq ~] getenforce Disabled 我的现在是关闭 ...

  8. CentOS7安装.Net Core2.2

    一.安装.Dotnet Core 2.2 Runtime Linux上运行Dotnet  Core程序的前提是安装Dotnet Core Runtime .Net Core对不同的Linux版本提示了 ...

  9. 谈个人对avascript面向对象的理解

    javascript,不但是javascript或者是别的语音,大多数都有一句经典的话:一切皆对象. 下面谈谈我个人对面向对象的理解,为什么要用面向对象来写js,这话我思考了很久,最后得出的结论就是: ...

  10. HTML5页面CSS Reset

    /*------------------*//*reset*//*------------------*/* {box-sizing: border-box; -webkit-tap-highligh ...