逆波兰表达式

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

    package com.hanqi.test; import java.sql.Connection; import java.sql.DriverManager; import java.sql.R ...

  2. 课时49.非input标签(掌握)

    1.select标签(下拉列表) 什么是下拉列表? 这就是下拉列表 作用: 用于定义下拉列表 格式: <select> <option>列表数据</option> ...

  3. mybatis调用存过程返回结果集和out参数值

    Mapper文件: 1.配置一个参数映射集,采用hashMap对象 2.使用call调用存储过,其中in out等标识的参数需要有详细的描述,例如:mode,JavaType,jdbcType等 &l ...

  4. Postgresql 入门笔记

    引言     最近整理了一些PostgreSQL的 常用命令,仅供参考   1. 入门命令 # 重启数据库 $ service postgresql-9.5 restart # 登陆: $ psql ...

  5. laravel 安装添加多站点

    官方文档如下 https://learnku.com/laravel/t/1160/laravel-nginx-multi-site-configuration

  6. Java开发小技巧(五):HttpClient工具类

    前言 大多数Java应用程序都会通过HTTP协议来调用接口访问各种网络资源,JDK也提供了相应的HTTP工具包,但是使用起来不够方便灵活,所以我们可以利用Apache的HttpClient来封装一个具 ...

  7. python3的下载与安装

    python3的下载与安装 1.首先,从Python官方网站:http://python.org/getit/ ,下载Windows的安装包 ython官网有几个下载文件,有什么区别?Python 3 ...

  8. centos升级数据库

    Centos下升级MySQL数据库 备份数据 $ mysqldump -u xxx -h xxx -P 3306 -p --all-databases > databases.sql 查看版本 ...

  9. 数据结构之 AVL个人笔记

    从这位前辈的博客园中学习的数据结构:https://www.cnblogs.com/skywang12345/ 非常感谢这位前辈. 以下文章摘录于 :skywang12345的博客园:转载请注明出处: ...

  10. ggplot2画简单的heatmap

    gg_heatmap gg_heatmap PeRl ggplot2 heatmap 偶然的机会,发现ggplot2画的heatmap也挺好看的,除了不能画出聚类树来(手动滑稽). 随意新建了两个矩阵 ...