逆波兰表达式

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

    题目描述] 今年是国际数学联盟确定的“2000——世界数学年”,又恰逢我国著名数学家华罗庚先生诞辰90周年.在华罗庚先生的家乡江苏金坛,组织了一场别开生面的数学智力竞赛的活动,你的一个好朋友XZ也有幸 ...

  2. qsort()与sort的用法(收藏)

    sort()函数是C++中的排序函数其头文件为:#include<algorithm>头文件: qsort()是C中的排序函数,其头文件为:#include<stdlib.h> ...

  3. mysql where 加 多个 或者条件

    select * from table where id=1 and uid=2 and (status=2 or status=3 or status=4);

  4. Oracle树形结构数据-相关知识总结

    Oracle树形结构数据--基本知识 1.数据组成 2.基本查询 2.1.查询某节点及该节点下的所有子孙节点 SELECT   *      FROM QIANCODE.TREE_TABLE_BASI ...

  5. 快速排序_c++

    快速排序_c++ GitHub 文解 快速排序正如其名,是一种排序速度较快的排序算法. 其核心思想: 取数组的第一个数,确定其在整个数组中的位置. 以刚刚的数值所确定的位置经数组分为两个部分. 再分别 ...

  6. JavaScript高级程序设计(复制变量值、传递参数)

    复制变量值 一个变量向另一个变量复制基本类型值和引用类型值时,是存在不同的. 一个变量向另一个变量复制基本类型的值,会在变量的对象上创建一个新值,然后把该值复制到为新变量分配的位置上. var num ...

  7. js取一个对象中的另一个对象

    最开始的截图 原本是想取到其中的foodName 先是用一个for循环循环了下 for (var i=0;i<res.data.length;i++) { this.goodsList.res. ...

  8. redux和react-redux的使用详解

    我自己的理解redux就跟vue中的vuex差不多,都是数据管理器,话不多说,我们从经典的计数器案例开始讲解 使用redux实现计数器 创建如下的react项目,我习惯把每一个模块分块,才有这么多文件 ...

  9. C++分享笔记:5X5单词字谜游戏设计

    笔者在大学二年级刚学完C++程序设计后,做过一次课程设计,题目是:5X5单词字谜游戏设计.为了设计算法并编写程序,笔者在当时颇费了一番心力,最后还是成功地完成了.设计中不乏有精妙之处.该程序设计完全是 ...

  10. 持续集成(CI – Continuous Integration)

    持续集成(CI – Continuous Integration) 在传统的软件开发中,整合过程通常在每个人完成工作之后.在项目结束阶段进行.整合过程通常需要数周乃至数月的时间,可能会非常痛苦.持续集 ...