栈的应用——表达式求值
概要
表达式求值问题可以说是一个经典问题。具体思路就是首先把输入的中缀表达式转换为后缀表达式,然后再根据后缀表达式进行计算求值。
中缀表达式转换为后缀表达式
首先我们设定运算符在进栈前与进栈后的优先级:
- 首先在栈把“#”进行压栈,并在中缀表达式追加“#”。“#”作为结束标志。
- 对中缀表达式进行遍历,遇到数字进行输出到后缀表达式中
- 如果遇到运算符,把栈顶的元素(前者)的栈内优先级与即将入栈元素(后者)的栈外优先级进行比较,如前者小,则运算符入栈,否则,则把栈顶元素(前者)出栈并输出到后缀表达式中,然后把后者入栈。
- 循环2,3两步直至中缀表达式的尾部的“#”。
后缀表达式求值
对后缀表达式进行遍历,如果是数字就入栈,如果是运算符,就连续出栈两次的结果进行保存,之后进行相应运算,把运算结果入栈,直至遍历结束,结果为栈顶元素。
下面是具体代码,但是为了减小码量,下面的程序对输入数字有如下要求:必须是0-9的数字,大于等于10不行,即如表达式:(1+(10-5)*2+2)/2是不合法的,10以上的数字不能出现。
#include <iostream>
#include <cstring>
#include <string>
using namespace std;//这是把中缀表达式转化成后缀表达式的类
class Transform{private:char* str;int top;int size;public://表达式求值的构造函数 Transform(int size){this->size = size;str = new char[size];top = -1;}//栈是否为空的函数bool IsEmpty(){return top == -1;}//栈是否已满的函数bool IsFull(){return top == this->size-1;}//入栈函数void Push(char ch){if(!this->IsFull()){this->str[++top] = ch; }}//获得栈顶元素 char Top(){return this->str[top];}//出栈函数void Pop(){this->top--;} //栈外运算符优先级 int icp(char ch){int result = 0;if(ch == '#'){result = 0;}if(ch == '('){result = 6;}if(ch == '*'||ch == '/'){result = 4;}if(ch == '+'||ch == '-'){result = 2;} if(ch == ')'){result = 1;}return result; }//栈内运算符优先级 int isp(char ch){int result = 0;if(ch == '#'){result = 0;}if(ch == '('){result = 1;}if(ch == '*'||ch == '/'){result = 5;}if(ch == '+'||ch == '-'){result = 3;} if(ch == ')'){result = 6;}return result; }//中缀表达式转为后缀表达式函数string Transform_Median(string median){//在中缀表达式和栈中追加"#"表示结束 median.append("#"); this->Push('#');char* c;int cnt = 0;char* tmp;c = new char[median.length()];tmp = new char[median.length()]; //后缀表达式的暂存数组 strcpy(c,median.c_str());for(int i = 0 ; i < median.length() ; i++){//如果是数字直接输出到后缀表达式中 if(c[i] >= '0' && c[i] <= '9'){tmp[cnt++] = c[i];}else{//如果不是数字,则需要和栈顶元素比较运算符优先级 char ch = this->Top();//栈顶元素在栈内的优先级比栈外元素的优先级高,则栈外元素入栈 if(this->isp(ch) < this->icp(c[i])){this->Push(c[i]); }else if(this->isp(ch) > this->icp(c[i])){//栈顶元素在栈内的优先级比栈外元素的优先级低//则栈内元素出栈,并输出到后缀表达式中,循环变量减1 tmp[cnt++] = ch;this->Pop();i--;}else{//栈顶元素在栈内的优先级等于栈外元素的优先级//说明已经运行到“#”,则出栈即可 this->Pop(); }}}//返回中缀表达式的字符串 string after = string(tmp,cnt);return after;}
}; //这是后缀表达式计算类
class Sum{private:int* sum;int top;int size;public://表达式求值的构造函数 Sum(int size){this->size = size;sum = new int[size];top = -1;}//栈是否为空的函数bool IsEmpty(){return top == -1;}//栈是否已满的函数bool IsFull(){return top == this->size-1;}//入栈函数void Push(int num){if(!this->IsFull()){this->sum[++top] = num; }}//获得栈顶元素 int Top(){return this->sum[top];}//出栈函数void Pop(){this->top--;} //后缀表达式求和int Sum_After(string after){char* s;s = new char[after.length()];strcpy(s,after.c_str());for(int i = 0 ; i < after.length() ; i++){if(s[i] >= '0' && s[i] <= '9'){this->Push(s[i]-'0');}else{int b = this->Top();this->Pop();int a = this->Top();this->Pop();int result = 0;switch(s[i]){case '+': result = a + b ;break;case '-': result = a - b ;break;case '*': result = a * b ;break;case '/': result = a / b ;break;};this->Push(result);}}return this->Top();}
};int main()
{string median;cout<<"请输入中缀表达式:"<<endl;cin>>median;Transform transform(median.length());string after = transform.Transform_Median(median);cout<<"后缀表达式为:"<<endl<<after<<endl;Sum sum(after.length()); int result = sum.Sum_After(after);cout<<"结果为:"<<endl<<result<<endl; return 0;}
栈的应用——表达式求值相关推荐
- php表达式求值,PHP实现基于栈的后缀表达式求值功能
本文实例讲述了PHP实现基于栈的后缀表达式求值功能.分享给大家供大家参考,具体如下: 后缀表达式概述 后缀表达式,指的是不包含括号,运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左 ...
- 栈实现算术表达式求值
算术表达式求值 利用栈求解的一个典型的问题是算术表达式求值,例如:"3+4*2-(1+1)#",这样的表达式计算,在计算过程中,不是读到一个运算就立即计算,而是要与后面的运算符进行 ...
- 数据结构课程设计---------用栈来实现表达式求值
1.需求分析 设计一个程序,演示用算符优先法对算术表达式求值的过程.利用算符优先关系,实现对算术四则混合运算表达式的求值. (1)输入的形式:表达式,例如2*(3+4) 包含的运算符只能有' ...
- 基于栈的后缀表达式求值(洛谷P1449题题解,Java语言描述)
题目要求 P1449题目链接 分析 给出后缀表达式求值,就相当于没了括号,而且很直接. 我们需要使用栈结构来完成任务. Java原装的栈使用了很多synchronized,导致性能不佳,但我们也就将就 ...
- 【Java】基于栈的算术表达式求值
定义异常类 public class ExpressionException extends RuntimeException {private static final long serialVer ...
- 栈的应用——表达式求值(双栈)
1.表达式求值 中缀表达式是正常的表达式形式, 例如:4.99 * 1.06 + 5.99 + 6.99 * 1.06 后缀表达式是针对中缀表达式而言的,可以理解为:操作符在两个操作数之后. 例如:4 ...
- 北京林业大学数据结构实验二 基于栈的算术表达式求值算法
第1关:基于栈的中缀算术表达式求值 参见课本P75 例3.3 #include <iostream> #include<iomanip>#define MAXSIZE 100 ...
- 编程题实训-实验2-基于栈的算术表达式求值算法(北京林业大学)
第1关:基于栈的中缀算术表达式求值 任务描述 本关任务:输入一个中缀算术表达式,求解表达式的值.运算符包括+.-.*./.(.).=,参加运算的数为double类型且为正数.(要求:直接针对中缀算术表 ...
- 数据结构栈之中缀表达式求值(实现计算器综合计算)
一.思路分析: 1.通过一个index值(索引),来遍历我们的表达式. 2.如果我们发现是一个数字,就直接入数栈. 3.如果发现扫描到是一个符号,就分如下情况: (1).如果发现当前的符号栈为空,就直 ...
最新文章
- UI设计培训技术分享:配色秘籍
- TYVJ1427 小白逛公园
- 【Nginx】解决 504 Gateway Time-out
- 10亿个字符串的排序问题
- shell结合expect写的批量scp脚本工具
- excel中怎样用公式获取表单控件_挑战高手:用不到 100 行代码,在前端实现 Excel 全部功能...
- 你的Parquet该升级了:IOException: totalValueCount == 0问题定位之旅
- Lazy Load Plugin for jQuery延迟加载测试成功
- sose会议级别_【2017年整理】计算机领域EI和SCI收录期刊、影响因子及国际会议.doc...
- java中md5加密和解密_java的MD5加密与解密
- 推荐5款常用编程文本编辑器
- 51单片机的红外遥控
- Python-伪数据构造神库Faker
- 因IP被列入黑名单导致U-Mail被退信的处理方法
- 自动回复的三种形式?
- java经典题之冒泡排序
- 2022眼视光展,护眼产品展,眼睛健康展,视力康复展
- HTML基础知识点总结
- 人工智能会拥有意识吗?
- C# 输入一个三位数的字符串,输出为三位数的整数,并输出百位、十位、和个位