C语言实现中缀转后缀并计算表达式结果
文章目录
- 一、问题描述
- 二、AC代码
- 三、注意点
- 四、实现思路/代码解析
一、问题描述
【问题描述】
从标准输入中读入一个整数算术运算表达式,如5 - 1 * 2 * 3 + 12 / 2 / 2 = 。计算表达式结果,并输出。
要求:
1、表达式运算符只有+、-、*、/,表达式末尾的’=’字符表示表达式输入结束,表达式中可能会出现空格;
2、表达式中不含圆括号,不会出现错误的表达式;
3、出现除号/时,以整数相除进行运算,结果仍为整数,例如:5/3结果应为1。
【输入形式】
在控制台中输入一个以’=’结尾的整数算术运算表达式。
【输出形式】
向控制台输出计算结果(为整数)。
【样例1输入】
5 - 1 * 2 * 3 + 12 / 2 / 2 =
【样例1输出】
2
二、AC代码
有点长
#include <stdio.h>
# define maxsize 1000typedef struct {int flag;//如果取1表示这个元素是整数,如果取0表示这个元素是运算符int num;char c;int level;
}opts;// 初始化堆栈
void initStack(int Top){Top=-1;
}// 测试堆栈是否为空
int isEmpty(int *Top){return *Top==0;//这里取0是因为我一开始把一个无关符号‘#’给压进去了,作为优先级最低的运算符,所以符号栈的栈底一直是这个无效符号
}// 测试堆栈是否已满
int isFull(int *Top){return *Top==maxsize-1;
}// 进栈
void push(opts s[],opts item,int *Top){if(isFull(&Top)){printf("the stack is full\n");return ;}else{s[++(*Top)]=item;}
}// 出栈
opts pop(opts s[],int *Top){if(isEmpty(&Top)){printf("the stack is empty\n");}elsereturn s[(*Top)--];
}// 中缀表达式
opts med[maxsize];
// 后缀表达式
opts post[maxsize];
//整个表达式的长度
int len;
//运算符栈
opts op[maxsize];
int Top_op=-1;
// 数字栈
int num[maxsize];
int Top_num=-1;
//注意,这个Top_XX是栈顶元素的下标,取-1时表示该栈为空int i;int main(){int a;char c;//输入while(1){scanf("%d %c",&a,&c);med[len].flag=1;med[len].num=a;len++;if(c=='=')break;med[len].flag=0;med[len].c=c;if(c=='*'||c=='/')med[len].level=2;if(c=='+'||c=='-')med[len].level=1;len++;}initStack(Top_num);initStack(Top_op);op[0].flag=0,op[0].level=0;//在符号栈中加入‘#’Top_op++;int j=0,k=0,l=0;//j是运算符栈,k是运算数栈,l是后缀表达式//开始中缀转后缀for(i=0;i<len;i++){if(med[i].flag==1){post[l++]=med[i];}if(med[i].flag==0){if(med[i].level>op[Top_op].level){push(op,med[i],&Top_op);}else{while (med[i].level<=op[Top_op].level){post[l++]=pop(op,&Top_op);}push(op,med[i],&Top_op);}}}//把符号栈中剩余的符号弹到后缀式中while (!isEmpty(&Top_op)){post[l++]=pop(op,&Top_op);}/* 打印后缀式for(i=0;i<len;i++){if(post[i].flag)printf("%d ",post[i].num);elseprintf("%c ",post[i].c);}*/int num1=0,num2=0;for(i=0;i<len;i++){// printf("i=%d,Top_num=%d\n",i,Top_num);if(post[i].flag){num[++Top_num]=post[i].num;
// printf("Top_num=%d\n",Top_num);}else{switch(post[i].c){case '+':num2=num[Top_num--];num1=num[Top_num--];num[++Top_num]=num1+num2;break;case '-':num2=num[Top_num--];num1=num[Top_num--];num[++Top_num]=num1-num2;break;case '*':num2=num[Top_num--];num1=num[Top_num--];num[++Top_num]=num1*num2;break;case '/':num2=num[Top_num--];num1=num[Top_num--];num[++Top_num]=num1/num2;break;}}}printf("%d\n",num[0]);}
三、注意点
这里就是提一下我一开始的错误,就是以为Top_XX是栈的长度,其实应该是栈顶元素的下标。
主要的注意事项主要分两部分,入栈和出栈
1)入栈:
入栈有3个条件
i)栈为空
ii)栈顶元素为左括号(
iii)栈顶运算符的优先级小于当前读入的运算符优先级,且当前运算符不是右括号)
2)出栈:
出栈有两种情况,读到了右括号需要出栈,优先级小于等于栈顶运算符优先级,但是不管怎么样都要满足栈不为空
i)如果读到了右括号:
在while循环中:保证栈顶元素不为左括号,一直到栈顶元素为左括号为止;
结束while循环后:并且while循环结束后还要把左括号弹出
ii)如果读到了非右括号:
在while循环中:保证(栈不为空&&栈顶元素不是左括号&&栈顶元素优先级大于等于当前运算符优先级)
结束while循环后:把当前运算符压入运算符栈中
四、实现思路/代码解析
1.主要的数据结构如下:
typedef struct {int flag;//如果取1表示这个元素是整数,如果取0表示这个元素是运算符int num;char c;int level;
}opts;// 中缀表达式
opts med[maxsize];
// 后缀表达式
opts post[maxsize];
int len;
//运算符栈
opts op[maxsize];
int Top_op=-1;
// 数字栈
int num[maxsize];
int Top_num=-1;
//注意,这个Top_XX是栈顶元素的下标,取-1时表示该栈为空
- 就是定义了一个结构体
opt
,存储运算数或者运算符,这个结构体有一个属性flag
,判断这个结构体是数还是运算符,如果是运算符,那这个结构体还会有一个属性level
,存储它的优先级 - 用两个opt数组
med[maxsize]
,post[maxsize]
,一个存储中缀表达式,一个存储后缀表达式 - 再用一个opt数组
op[maxsize]
+整型变量Top_op
,作为运算符栈和运算符栈的栈顶下标;这个栈是在中缀转后缀时起作用的 - 最后是整型数组
num[maxsize]
和整型变量Top_num
,作为运算数栈和运算数栈的下标,这个栈是在计算后缀表达式的值时起作用的 - 总之就是,运算符栈
op[maxsize]
只在中缀转后缀时起效,运算数栈num[maxsize]
只在计算后缀表达式时起作用
2.具体中缀转后缀的思路可以参考我的另一篇文章:中缀后缀表达式的转换
C语言实现中缀转后缀并计算表达式结果相关推荐
- C语言实现中缀转后缀表达式,并求值
C语言实现中缀转后缀表达式,并求值 #include <stdio.h> #include <stdlib.h> #include <ctype.h> #inclu ...
- 中缀 转 后缀 实现计算
文章目录 前言 一.后缀表达式 二.中缀转后缀 方式 三.中缀 转 后缀 并计算 实现 四.总结 前言 中缀表达式就是我们在进行加减乘除时经常使用的表达式,后缀表达式是对计算机友好的表达式,计算机可以 ...
- 中缀、后缀、前缀表达式
一.简介 对于1+((2*3)-4)/2 的数学表达式怎么求值? 分析: 数学表达式求值有优先级,不能简单的从左往右依次计算, 需要从优先级高的开始计算 中缀表达式是一种通用的算术或逻辑公式表示方法, ...
- 数据结构之栈实现中缀转后缀并计算结果
一.中缀变后缀过程分析 给定一个中缀,最后变为后缀的过程其实并不算复杂,下面分析一下过程: 1. 首先面对一个中缀表达式,我们需要两个栈,一个用来存放运算符,即符号栈 operatorstack,一个 ...
- java 中缀转后缀并计算_Java实现表达式计算(中缀转后缀)
定义: 中缀表达式:我们平时写的数学表达式一般为中缀表达式,如"5+2*(3*(3-1*2+1))",直接拿中缀表达式直接让计算机计算表达式的结果并不能做到. 后缀表达式:把中缀表 ...
- 【C语言】中缀转后缀(头歌数据结构)
一.问题解析:过程分为两步: 第一步,是将输入的字符串处理,运算符和数字分类储存. 第二部,将中缀转后缀. 二.实现思路 首先来看第一步是如何实现的: 当传入一个字符串,我们需要对字符串的每一个字符根 ...
- java简易计算机(用栈实现中缀转后缀,计算后缀表达式)
这学期java课的一个小作业,用java编一个小计算器. 个人认为要点在于: 1.计算机的布局,即按钮和输出框的布局需要知道怎么操作,按钮的大小和字体的大小颜色.不同布局中按钮的改变大小等等 2.用栈 ...
- C语言实现 中缀转后缀
中缀表达式转后缀表达式 一.后缀表达式 中缀表达式就是我们平常所用的标准四则运算表达式 例如 " 9 +(3 - 1)× 3 + 10 ÷ 2 " 所有的符号都在运算数字的后面出现 ...
- 顺序栈计算器 中缀转后缀表达式
顺序栈计算器 中缀转后缀表达式 前言 一.后缀表达式简述 二.参考书目中的函数实现 1.输入一个后缀表达式并计算 2.将中缀转后缀表达式 三.在原方法基础上改写并结合两个方法 1.输入一个后缀表达式并 ...
最新文章
- 自媒体人怎样快速拥有自己的APP
- App设计灵感之十二组精美的酒店预定App设计案例
- 一个电子工程师的完美人生!
- 盘点最经典的外包案例
- 教材管理系统紧张开发中
- django入门记录 2
- 深入PHP面向对象、模式与实践读书笔记:面向对象设计和过程式编程
- 微信小程序开发:学习笔记[9]——本地数据缓存
- java.io.IOException: Server returned HTTP response code: 411 for URL
- oracle24801错误,[数据库]oracle错误(ORA
- 【JavsScript】webapp的优化整理
- 1114 Family Property (25 分)
- 编程c语言中文图形代码,C语言图形编程代码
- PSV遭到破解!reF00D让你在低版本执行新游戏
- Mybatis关联关系
- python爬虫,爬取贝壳网数据简单案例
- 《数学之美》知识点详细总结
- 20172301 2017-2018-2 《程序设计与数据结构》第十周学习总结
- Infor SunSystems咨询服务市场报告-市场规模、市场份额、市场定位、产品类型以及发展规划
- 回眸 2020,展望 2021