热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

利用栈实现四则运算表达式的高效求值方法

本文提出了一种基于栈结构的高效四则运算表达式求值方法。该方法能够处理包含加、减、乘、除运算符以及十进制整数和小括号的算术表达式。通过定义和实现栈的基本操作,如入栈、出栈和判空等,算法能够准确地解析并计算输入的表达式,最终输出其计算结果。此方法不仅提高了计算效率,还增强了对复杂表达式的处理能力。

要求从键盘输入一个算术表达式并输出它的结果,算术表达式可包含加、减、乘、除、十进制整数和小括号,利用栈实现。

首先我们需要定义两个栈的基本创建插入删除操作
数据栈:存放数据
操作符栈:存放操作符

#include
#include
typedef int ElemType;
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
typedef struct //定义数据栈(存放数据)
{ ElemType *base;ElemType *top;int stacksize;}SqStack; typedef struct //定义操作符栈 { char *base;char *top;int stacksize;}OpStack;
int InitStack(SqStack &s) //初始化数据栈
{ s.base=(ElemType *)malloc(STACK_INIT_SIZE*sizeof(ElemType));if(!s.base) return 0;s.top=s.base;s.stacksize=STACK_INIT_SIZE;return 1;} int Push(SqStack &s,ElemType e) //数据栈的进栈操作 { if(s.top-s.base>=s.stacksize){s.base=(ElemType *)realloc(s.base,(s.stacksize+STACKINCREMENT)*sizeof(ElemType)); if(!s.base) return 0;s.top=s.base+s.stacksize;s.stacksize+=STACKINCREMENT;}*s.top++=e;return 1;}int Pop(SqStack &s,ElemType &e) //数据栈的出栈操作 { if(!s.base) return 0;e=*--s.top;return 1;}int InitOpStack(OpStack &s) //初始化操作符栈
{ s.base=(char *)malloc(STACK_INIT_SIZE*sizeof(char));if(!s.base) return 0;s.top=s.base;s.stacksize=STACK_INIT_SIZE;return 1;} int OpPush(OpStack &s,char e) //操作符栈的进栈操作 { if(s.top-s.base>=s.stacksize){s.base=(char *)realloc(s.base,(s.stacksize+STACKINCREMENT)*sizeof(char)); if(!s.base) return 0;s.top=s.base+s.stacksize;s.stacksize+=STACKINCREMENT;}*s.top++=e;return 1;}int OpPop(OpStack &s,char &e) //操作符栈的出栈操作 { if(!s.base) return 0;e=*--s.top;return 1;}

然后定义一个运算符比较表来告诉系统这些基本运算符的优先顺序。

char Precede(char a1,char a2) //运算符比较表 { switch(a1){case &#39;&#43;&#39;:switch(a2){case &#39;&#43;&#39;:return &#39;>&#39;;case &#39;-&#39;:return &#39;>&#39;;case &#39;*&#39;:return &#39;<&#39;;case &#39;/&#39;:return &#39;<&#39;;case &#39;(&#39;:return &#39;<&#39;;case &#39;)&#39;:return &#39;>&#39;;case &#39;#&#39;:return &#39;>&#39;;}case &#39;-&#39;:switch(a2){case &#39;&#43;&#39;:return &#39;>&#39;;case &#39;-&#39;:return &#39;>&#39;;case &#39;*&#39;:return &#39;<&#39;;case &#39;/&#39;:return &#39;<&#39;;case &#39;(&#39;:return &#39;<&#39;;case &#39;)&#39;:return &#39;>&#39;;case &#39;#&#39;:return &#39;>&#39;;}case &#39;*&#39;:switch(a2){case &#39;&#43;&#39;:return &#39;>&#39;;case &#39;-&#39;:return &#39;>&#39;;case &#39;*&#39;:return &#39;>&#39;;case &#39;/&#39;:return &#39;>&#39;;case &#39;(&#39;:return &#39;<&#39;;case &#39;)&#39;:return &#39;>&#39;;case &#39;#&#39;:return &#39;>&#39;; }case &#39;/&#39;:switch(a2){case &#39;&#43;&#39;:return &#39;>&#39;;case &#39;-&#39;:return &#39;>&#39;;case &#39;*&#39;:return &#39;>&#39;;case &#39;/&#39;:return &#39;>&#39;;case &#39;(&#39;:return &#39;<&#39;;case &#39;)&#39;:return &#39;>&#39;;case &#39;#&#39;:return &#39;>&#39;;}case &#39;(&#39;:switch(a2){case &#39;&#43;&#39;:return &#39;<&#39;;case &#39;-&#39;:return &#39;<&#39;;case &#39;*&#39;:return &#39;<&#39;;case &#39;/&#39;:return &#39;<&#39;;case &#39;(&#39;:return &#39;<&#39;;case &#39;)&#39;:return &#39;&#61;&#39;;case &#39;#&#39;:return 0;}case &#39;)&#39;:switch(a2){case &#39;&#43;&#39;:return &#39;>&#39;;case &#39;-&#39;:return &#39;>&#39;;case &#39;*&#39;:return &#39;>&#39;;case &#39;/&#39;:return &#39;>&#39;;case &#39;(&#39;:return 0;case &#39;)&#39;:return &#39;>&#39;;case &#39;#&#39;:return &#39;>&#39;;}case &#39;#&#39;:switch(a2){case &#39;&#43;&#39;:return &#39;<&#39;;case &#39;-&#39;:return &#39;<&#39;;case &#39;*&#39;:return &#39;<&#39;;case &#39;/&#39;:return &#39;<&#39;;case &#39;(&#39;:return &#39;<&#39;;case &#39;)&#39;:return 0;case &#39;#&#39;:return &#39;&#61;&#39;;}}}

定义函数&#xff08;对从栈顶取出的两个数进行操作&#xff09;

ElemType Operate(ElemType a,char theta,ElemType b) //两个数的操作
{ ElemType sum;switch(theta) //对传递的运算符进行相应操作 { case &#39;&#43;&#39;:sum&#61;a&#43;b;break;case &#39;-&#39;:sum&#61;a-b;break;case &#39;*&#39;:sum&#61;a*b;break;case &#39;/&#39;:sum&#61;a/b;break; }return sum;
}

然后通过表达式求值算法函数调用前面所说函数进行计算

int EvaluateExpression() //表达式求值 { SqStack OPND;OpStack OPTR;int flag&#61;0; //标志变量 判断连续进数字栈的个数 char c,e,theta; //c为输入字符 e&#xff0c;theta为下面删除变量 ElemType b,a; //ba为下面的删除变量 InitOpStack(OPTR);OpPush(OPTR,&#39;#&#39;); //初始化两个栈 并且将#进入操作符栈底 InitStack(OPND);printf("输入表达式(输入#结束)&#xff1a;\n");c&#61;getchar();while(c!&#61;&#39;#&#39;||*(OPTR.top-1)!&#61;&#39;#&#39;) //当输入的字符不为#或者操作符栈顶指针不指向栈底 { if(c>&#61;&#39;0&#39;&&c<&#61;&#39;9&#39;) //如果字符为数字 { Push(OPND,c-48); //进数字栈 if(flag!&#61;0) //如果数字高于10位数 { Pop(OPND,b);Pop(OPND,a);Push(OPND,a*10&#43;b); //把计算出来的结果重新入栈 flag&#61;0;}flag&#61;1;c&#61;getchar();}else //如果为运算符 {switch(Precede(*(OPTR.top-1),c)) //比较操作符栈顶指针与输入字符优先级 { case &#39;<&#39;:OpPush(OPTR,c);flag&#61;0;c&#61;getchar();break;//如果小于 继续进栈 case &#39;&#61;&#39;:OpPop(OPTR,e);flag&#61;0;c&#61;getchar();break; //等于 删除 case &#39;>&#39;:OpPop(OPTR,theta);flag&#61;0;Pop(OPND,b);Pop(OPND,a); //大于 提取数字栈顶的两个数进行运算 Push(OPND,Operate(a,theta,b)); //将运算完成的数进栈 break;}}}printf("表达式的值&#61;:%d",*(OPND.top-1)); return 1;}

然后在主函数中调用&#xff0c;查看运行结果

int main(){ EvaluateExpression();return 0;}

在这里插入图片描述


推荐阅读
  • A题简单判断#includeusingnamespacestd;typedeflonglongll;intt;intmain(){cint;whil ... [详细]
  • 题目描述:孩子们围坐在一起,分享水果,场面温馨。然而,由于孩子们身高不同,排队时显得高低不齐。给定孩子们的身高序列,通过交换某些孩子的顺序,计算每次交换后的序列混乱度。 ... [详细]
  • 本文档提供了数据结构在C语言中的实现示例,特别是解决二次方程的代码片段,以及《数据结构(用面向对象方法与C++语言描述)第二版》的部分习题答案。 ... [详细]
  • C++编程基础:探索自定义数据类型
    本文继续深入C++编程的基础知识,重点讲解自定义数据类型的概念及其应用,包括枚举类型、结构体和联合体等。 ... [详细]
  • 双连通分量(biconnectedcomponent,简称bcc)概念:双连通分量有点双连通分量和边双连通分量两种。若一个无向图中的去掉任意一个节点( ... [详细]
  • 近期参加了一次CSDN线上活动,有幸获得左飞老师的《算法之美——隐匿在数据结构背后的原理(C++版)》一书。为了加深理解并提升编程技能,我决定将书中22个经典算法问题使用Java语言进行重新编写。本文将重点介绍如何使用Java实现Z字形矩阵排列。 ... [详细]
  • Flutter入门指南:实现自动关闭的对话框与提示
    本文为Flutter系列教程的一部分,专注于讲解如何在Flutter应用中实现自动关闭的对话框和提示。通过具体的代码示例,帮助开发者掌握SnackBar、BottomSheet和Dialog的使用方法。 ... [详细]
  • 快速排序是一种高效的排序算法,以其在多数情况下接近最优的性能而著称。本文将详细介绍如何在 Java 中实现快速排序,并分析其工作原理。 ... [详细]
  • mysql 分库分表策略_【数据库】分库分表策略
    关系型数据库本身比较容易成为系统瓶颈,单机存储容量、连接数、处理能力都有限。当单表的数据量达到1000W或100G以后,由于查询维度较多, ... [详细]
  • 本文详细探讨了 Java 中状态模式与策略模式的核心差异,旨在帮助开发者在实际应用中准确选择和运用这些设计模式。 ... [详细]
  • 本文详细介绍了RocketMQ中的消息并发消费机制,包括消息拉取后的处理流程、消费服务的调用以及消费任务的具体执行过程。 ... [详细]
  • 本文介绍了一个使用C++编写的算法,用于从给定的字符串中找出最长的连续重复子串。例如,对于输入字符串“ababc”,算法将返回“ab”。文中不仅提供了详细的代码实现,还分析了算法的时间和空间复杂度。 ... [详细]
  • VSCode中使用Clang-Format进行C/C++代码格式化配置
    本文介绍了如何在VSCode中配置Clang-Format以实现C/C++代码的自动格式化,包括安装必要的扩展、配置文件的创建以及常用设置的解释。建议阅读官方文档以获取更多详细信息。 ... [详细]
  • 剑指Offer算法题解析:实现带Min方法的栈
    本文深入探讨了《剑指Offer》系列中的一道经典算法题——设计一个支持常数时间内检索最小元素的栈。通过详细分析与代码示例,帮助读者理解并掌握这一问题的核心解法。 ... [详细]
  • 本文详细介绍了Redis中对象的内部结构,包括数据类型、编码方式、最近访问时间(LRU)和引用计数等关键属性。通过这些属性,Redis能够高效地管理和优化内存使用。 ... [详细]
author-avatar
天秤小果冻cici
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有