当前位置:网站首页>算术表达式求值演示
算术表达式求值演示
2022-08-09 08:55:00 【面向01编程】
算术表达式求值演示-严蔚敏版数据结构课设
后缀表达式应用
实现代码:
```cpp
#include <iostream>
#include <malloc.h>
#include <cstring>
#include <iomanip>
#include <math.h>
using namespace std;
#define STACK_INIT_SIZE 100 //存储空间初始分配量
#define STACK_INCREMENT_SIZE 20 //存储空间增量
#define OVERFLOW -2
#define OK 1
#define ERROR 0
#define FALSE 0
#define TRUE 1
typedef int Status;
typedef struct node{
double num;//数字
char op;//操作符
bool flag;//判断是数字还是操作符,1为数字
}node;
typedef node ElemType;
typedef struct {
ElemType * base;
ElemType * top;
int stacksize;
}SqStack; //定义栈结构体
Status InitStack(SqStack &S){
//初始化栈
S.base = (ElemType *) malloc(STACK_INIT_SIZE *sizeof(ElemType));
if(!S.base) exit(OVERFLOW);
S.top = S.base;
S.stacksize = STACK_INIT_SIZE;
return OK;
}
Status StackEmpty(SqStack S){
//判断栈是否为空
if(S.base == S.top) return TRUE;
else return FALSE;
}
Status ClearStack(SqStack &S)
{ // 把S置为空栈
S.top=S.base;
return OK;
}
ElemType GetTop(SqStack S){
//用e返回栈顶元素
if(StackEmpty(S)) exit (ERROR);
return *(S.top-1);
}
Status Push(SqStack &S,ElemType e){
//将e压入栈
if(S.top - S.base >= S.stacksize) {
//栈满,增加分配空间
S.base = (ElemType *) realloc (S.base , (S.stacksize+STACK_INCREMENT_SIZE) * sizeof(ElemType));
if(!S.base) exit(OVERFLOW); //分配失败
S.top = S.base + S.stacksize;
S.stacksize += STACK_INCREMENT_SIZE;
}
* S.top++ = e;
return OK;
}
Status Pop(SqStack &S) {
//将栈顶元素出栈
if(S.base == S.top) return ERROR;
--S.top;
return OK;
}
Status StackTraverse(SqStack S)
{ //
if(S.top==S.base) {
cout<<"这里什么也没有!"<<endl;
return ERROR;
}
ElemType * p;
p=S.base;
while(p<S.top)
{
if((*p).flag==0){
cout<<(*p).op<<' ';
}
else cout<<(*p).num<<' ';
p++;
}
cout<<endl;
return OK;
}
Status isNumber(char ch){
if(ch >='0' && ch<= '9') return TRUE;
else return FALSE;
}
int Precede(char c){
if (c <= '9' && c >= '0')
return 5;
else if (c <= 'z' && c >= 'a')
return 6;
else if (c <= 'Z' && c >= 'A')
return 6;
else if (c == '.')
return 7;
else {
switch (c) {
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
case '(':
return 4;
case ')':
return 3;
default:
return 0;
}
}
}
Status TansPost(SqStack &PostStack,SqStack & Op,string cs){
double num=0;//暂时存储小数部分值
ElemType temp;
int i=0;
if(cs[i]=='-'){//表达式首位为'-'情况,先在后缀表达式前添加零,达到实现负数目的
temp.flag=true;
temp.num=0;
Push(PostStack,temp);
}
while(i<cs.length()){
if(cs[i]==')'){
while(!StackEmpty(Op)&& GetTop(Op).op!='('){
Push(PostStack,GetTop(Op));
Pop(Op);
}
Pop(Op);//弹出左括号
i++;
}
else if(cs[i]=='('){
temp.flag =false;
temp.op=cs[i];
Push(Op,temp);
i++;
if(cs[i]=='-'&&isNumber(cs[i+1])){//得到负数
temp.flag=true;
temp.num=cs[++i]-'0';i++;
while(i<cs.length() && isNumber(cs[i])){
temp.num = temp.num *10 +(cs[i]-'0');
i++;
}//整数部分计算完成
if(cs[i]=='.'){
i++;
double j=1;
while(i<cs.length() && isNumber(cs[i])){
num += pow(0.1,j) * (cs[i]-'0');
i++;j++;
}
}
temp.num +=num;
num=0;//下一次继续使用
temp.num=0-temp.num;
Push(PostStack,temp);
}
}
else if(isNumber(cs[i])){
temp.flag=true;
temp.num=cs[i++]-'0';
while(i<cs.length() && isNumber(cs[i])){
temp.num = temp.num *10 +(cs[i]-'0');
i++;
}//整数部分计算完成
if(cs[i]=='.'){
i++;
double j=1;
while(i<cs.length() && isNumber(cs[i])){
num += pow(0.1,j) * (cs[i]-'0');
i++;j++;
}
}
temp.num +=num;
num=0;//下一次继续使用
Push(PostStack,temp);
}
else {//需要增加一个条件是不不能够遇上左括号
temp.flag =false;
while(!StackEmpty(Op) && GetTop(Op).op!='(' &&
Precede(cs[i])<=Precede(GetTop(Op).op)){
Push(PostStack,GetTop(Op));
Pop(Op);
}
temp.op=cs[i];
Push(Op,temp);
++i;
}
}
while(!StackEmpty(Op)){//将Op栈全部压入后缀表达式逆序
Push(PostStack,GetTop(Op));
Pop(Op);
}
cout<<"后缀表达式:";
StackTraverse(PostStack);
}
double Calculate(SqStack & PostStack_temp,SqStack & Op){//此时Op作为辅助后缀表达式的计算栈
double temp1,temp2;
node cur ,temp;
SqStack PostStack;InitStack(PostStack);
while(!StackEmpty(PostStack_temp)){//逆序才是后缀表达式
Push(PostStack,GetTop(PostStack_temp));
Pop(PostStack_temp);
}
while(!StackEmpty(PostStack)){
cur =GetTop(PostStack);
Pop(PostStack);
if(cur.flag == true) Push(Op,cur);
else {
temp2 = GetTop(Op).num;
Pop(Op);
temp1 = GetTop(Op).num;
Pop(Op);
temp.flag = true;
if (cur.op == '+') temp.num = temp1 + temp2;
else if(cur.op == '-') temp.num = temp1 - temp2;
else if(cur.op == '*') temp.num = temp1 * temp2;
else temp.num = temp1 / temp2;
Push(Op,temp);
}
}
return GetTop(Op).num;
}
int main(){
string cs;
SqStack PostStack,Op;
InitStack(PostStack); InitStack(Op);
while(1){
cout<<"请输入要计算的表达式:";
cin>>cs;cout<<endl;
TansPost(PostStack,Op,cs);
cout<<'\n';
cout<<"计算结果:";
cout<<cs<<" = ";
cout<<fixed<<setprecision(2)<<Calculate(PostStack,Op)<<'\n'<<endl;
cs.erase(0);ClearStack(PostStack);ClearStack(Op); //清空字符串和两个栈,便于循环计算
cout<<'\n'<<'\n'<<'\n';
}
return 0;
}
边栏推荐
- epoll LT和ET 问题总结
- Account and Permission Management
- makefile - 学习小结
- ASEMI整流桥GBJ810参数,GBJ810封装,GBJ810重量
- How does STM32 know the usage of FLASH
- 【MySQL】mysql:解决[Err] 1093 - You can‘t specify target table ‘表名‘ for update in FROM clause问题
- leetcode 37. 解数独 (困难)
- 黑马2022最新redis课程笔记知识点(面试用)
- 数制之间的转换
- Object detection app based on appinventor and EasyDL object detection API
猜你喜欢
Dark Horse 2022 latest redis course notes and knowledge points (for interview)
GBJ610-ASEMI超薄整流扁桥GBJ610
Venture DAO 行业研报:宏观和经典案例分析、模式总结、未来建议
XCTF高校战“疫”网络安全分享赛Misc wp
【场景化解决方案】构建门店通讯录,“门店通”实现零售门店标准化运营
Tencent cloud server is modified to root login to install pagoda panel
静态路由原理与配置
电子产品整机结构设计的一般性思路
RESTful
【redis】使用redis实现简单的分布式锁,秒杀并发场景可用
随机推荐
QT设置exe可执行文件的图标
6000 字+,帮你搞懂互联网架构演变历程!
嵌入式之串口中断只能收到一个字节
【场景化解决方案】构建门店通讯录,“门店通”实现零售门店标准化运营
Programming a washing machine: garbled characters after string output
[V&N2020 公开赛]内存取证
Introduction to Network Layer Protocols
Xpath之爬取全国城市名称学习
+ 6000 words, help you understand the Internet architecture evolution.
100句话,是否会触动你?
电子产品整机结构设计的一般性思路
网络层协议介绍
ASEMI整流桥GBJ810参数,GBJ810封装,GBJ810重量
The difference between big-endian and little-endian storage is easy to understand at a glance
VNCTF2021 部分题目复现
交换机的工作原理
Where does detection go forward?
Makefile中patsubst、wildcard、notdir的使用
PoPW代币分配机制或将点燃下一个牛市
Shell编程之循环语句与函数