• 题目:算术表达式求值

题目描述:表达式计算是实现程序设计语言的基本问题之一,也是栈的应用的一个典型例子。设计一个程序,演示用运算符优先法对算数表达式求值的过程。
基本要求:以字符序列的形式从终端输入语法正确的、不含变量的整数表达式。利用教科书表3.1给出的运算符优先关系,实现对算数四则混合运算表达式的求值,并仿照教科书的例3.1演示在求值中运算符栈、运算数栈、输入字符和主要操作的变化过程。
测试数据:
1+2+3+4
88-15
1024/4
8
1024/(48)
(20+2)
(6/2)
3-3-3
2*(6+2*(3+6*(6+6)))
(((6+6)*6+3)*2+6)*2

  • 算法思想

首先,将输入的字符分为两种类型:运算数运算符。顾名思义,运算数就是参与运算的整数。运算符指加减乘除,左右括号以及‘#’,其中‘#’用于标记输入的开始与结束,起一个标识的作用。也就是说,用户的输入必须以‘#’作为结束。
为实现上述程序功能,选择栈用于存储运算符与运算数,分别用两个栈oprtnum来存储。首先在oprt栈中压入一个‘#’,用以提示程序表达式的边界。从终端读取数据:
如果读到的是数字字符,那么表明现在正在输入的是运算数。为了得到完整的数字,先将这些数字字符按顺序存储到缓冲区(temp栈),直到读到运算符时,将缓冲区的数字按照权重相加,构造出完整的运算数,压入运算数栈中去,同时清空temp栈。
如果读到的是运算符,那么按照规则比较oprt栈顶运算符和此运算符的优先级:(下列三种情况)
a.oprt栈顶运算符高于此运算符,则表明此时已经可以进行计算。将num栈依次出栈两个元素A,B,则由B、oprt栈顶运算符、A构成了一个简单的表达式,对之进行计算,将结果压入num栈。
b.oprt栈顶运算符低于此运算符,则先将这个运算符入栈,然后继续读取。
c.oprt栈顶运算符优先级等于此运算符,例如左右括号匹配时、表达式头‘#’和尾‘#’匹配时,则不将此运算符入栈,反而将oprt栈顶运算符出栈。

重复上述①②操作,直到oprt栈顶元素为‘#’或读取到的字符为‘#’(结束)。此时num栈顶元素即为此表达式的结果。


上图为运算优先级关系图

  1. 上代码
#include<stdio.h>
#include<stdlib.h>
#define defaultsize 10
#define increasesize 5
typedef struct{char *base;char *top;int stacksize;//栈的存储容量
}OPRTstack;
typedef struct{double *base;double *top;int stacksize;
}NUMstack;
int createStack(OPRTstack*s)
{s->base=(char*)malloc(sizeof(char)*defaultsize);if(!s->base)return 0;s->top=s->base;s->stacksize=10;return 1;
}
int pop(OPRTstack *s,char *e)
{if(s->top==s->base)return 0;s->top--;*e=*(s->top);return 1;
}
int push(OPRTstack*s,char e)
{if(s->top-s->base>=s->stacksize){s->base=(char*)realloc(s->base,sizeof(char)*(s->stacksize+increasesize));if(!s->base)return 0;s->top=s->base+s->stacksize;s->stacksize+=increasesize;}*(s->top)=e;s->top++;
}
int isEmpty(OPRTstack *s)
{if(s->top==s->base)return 1;else return 0;
}
char GetTop(OPRTstack *s)
{if(!isEmpty(s)){char*temp=s->top;temp--;return *(temp);}else return '!';//这样定义的话,栈里面不能存储!这个数据
}
void showStack(OPRTstack*s)
{if(isEmpty(s))return ;for(int i=0;i<s->top-s->base;i++){printf("%c ",s->base[i]);}printf("  ");
}
//看起来代码很多,其实下面的函数定义和上面的几乎一模一样,只是传递的参数不同而已int createStack(NUMstack*s)
{s->base=(double*)malloc(sizeof(double)*defaultsize);if(!s->base)return 0;s->top=s->base;s->stacksize=10;return 1;
}
int pop(NUMstack *s,double *e)
{if(s->top==s->base)return 0;s->top--;*e=*(s->top);return 1;
}
int push(NUMstack*s,double e)
{if(s->top-s->base>=s->stacksize){s->base=(double*)realloc(s->base,sizeof(double)*(s->stacksize+increasesize));if(!s->base)return 0;s->top=s->base+s->stacksize;s->stacksize+=increasesize;}*(s->top)=e;s->top++;
}
int isEmpty(NUMstack *s)
{if(s->top==s->base)return 1;else return 0;
}
double GetTop(NUMstack *s)
{if(!isEmpty(s)){double *temp=s->top;temp--;return *(temp);}else return -1;//这样定义的话,栈里面不能存储!这个数据
}
void showStack(NUMstack*s)
{if(isEmpty(s))return ;for(int i=0;i<s->top-s->base;i++){printf("%f ",s->base[i]);}printf("  ");
}int isOPRT(char c)//判断c是不是运算符
{if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='#')return 1;else return 0;
}
char compare(char a,char b)
{if(a=='+'){if(b=='*'||b=='/'||b=='(') return '<';else return '>';}else if(a=='-'){if(b=='*'||b=='/'||b=='(') return '<';else return '>';}else if(a=='*'){if(b=='(')return '<';else return '>';}else if(a=='/'){if(b=='(')return '<';else return '>';}else if(a=='('){if(b==')')return '=';else if(b=='#') return '!';else return '<';}else if(a==')'){if(b=='(')return '!';else return '>';}else if(a=='#'){if(b==')')return '!';if(b=='#')return '=';else return '<';}
}
double calculate(double left,double right, char operators)
{switch(operators){case '+':return left+right;case '-':return 1.0*left-right;case '*':return left*right;case '/':return 1.0*left/right;}
}int main()
{OPRTstack oprt;//运算符栈 NUMstack  num;//运算数字栈 NUMstack temp;//缓冲区,用于构建完整的运算数字 int build=0;//由若干数位构成的数字 double index;//某个数位上的数字 int complex=1;//10的幂次 char operators;//基本表达式中的四则运算符 double left,right;//基本表达式中左右运算数字 createStack(&num);createStack(&oprt);createStack(&temp);printf("键入运算表达式,以#结束\n"); push(&oprt,'#');char c=getchar();int error=0;//syntax error 标识符 while(c!='#'||GetTop(&oprt)!='#'){while(!isOPRT(c))//读入的是数字 {push(&temp,c-'0');c=getchar();}while(!isEmpty(&temp))//将读取到的数字字符存入缓冲区,构建完整的运算数字 {pop(&temp,&index);build+=(index*complex);complex*=10 ;}complex=1;if(build)push(&num,double(build));//将此运算数字压入栈num printf("\n运算符栈:");showStack(&oprt);printf("运算数栈:");showStack(&num);//每次压栈弹栈都需要打印信息 build=0;if(isOPRT(c))//读入的是运算符 {switch(compare(GetTop(&oprt),c)){case '<':push(&oprt,c);c=getchar();printf("\n运算符栈:");showStack(&oprt);printf("运算数栈:");showStack(&num); break;case '=':pop(&oprt,&operators);c=getchar();printf("\n运算符栈:");showStack(&oprt);printf("运算数栈:");showStack(&num);break;case '>':pop(&oprt,&operators);pop(&num,&right);pop(&num,&left);push(&num,calculate(left,right,operators));//从num栈弹出两个运算数字,利用运算符栈顶元素进行计算 printf("\n运算符栈:");showStack(&oprt);printf("运算数栈:");showStack(&num);break;case '!':printf("Syntax Error!");error=1;break;}}if(error)break;}if(!error)printf("结果为:%f",GetTop(&num));return 0;
}
  • 运行结果
    测试数据8:(((6+6)*6+3)*2+6)*2#
    输出:312.000000

算术表达式求值(C语言栈)相关推荐

  1. c语言作业算术表达式求值,算术表达式求值演示(C语言版)

    //头文件预处理命令 #include #include //----------函数结果状态代码----------------- #define TRUE 1 #define FALSE 0 #d ...

  2. 【Java】基于栈的算术表达式求值

    定义异常类 public class ExpressionException extends RuntimeException {private static final long serialVer ...

  3. 《Algorithms》—— Dijkstra 的双栈算术表达式求值算法

    想当年学数据结构的时候,一直觉得这个是我一辈子都搞不懂的一个东西.现在看看...还挺简单的... 重点在于如何解析由括号.运算符和数字组成的字符串,并按照正确的顺序完成各种初级算术操作.利用了两个栈( ...

  4. 【数据结构】栈的应用-算术表达式求值#数据结构实验任务书

    实验题目:栈的应用-算术表达式求值 正文 实验环境: Visual C++ 2010 实验目的: 1.掌握栈的定义及实现: 2.掌握利用栈求解算术表达式的方法. 实验内容: 通过修改完善教材中的算法3 ...

  5. 栈实现算术表达式求值

    算术表达式求值 利用栈求解的一个典型的问题是算术表达式求值,例如:"3+4*2-(1+1)#",这样的表达式计算,在计算过程中,不是读到一个运算就立即计算,而是要与后面的运算符进行 ...

  6. 北京林业大学数据结构实验二 基于栈的算术表达式求值算法

    第1关:基于栈的中缀算术表达式求值 参见课本P75 例3.3 #include <iostream> #include<iomanip>#define MAXSIZE 100 ...

  7. 编程题实训-实验2-基于栈的算术表达式求值算法(北京林业大学)

    第1关:基于栈的中缀算术表达式求值 任务描述 本关任务:输入一个中缀算术表达式,求解表达式的值.运算符包括+.-.*./.(.).=,参加运算的数为double类型且为正数.(要求:直接针对中缀算术表 ...

  8. 算术表达式求值演示(C/C++实现)

    算术表达式求值演示 问题描述:表达式计算是实现程序设计语言的基本问题之一,也是栈的应用的典型例子.设计一个程序,演示用算符优先法对算术表达式求值的过程. 基本要求:以字符序列的形式从键盘输入语法正确的 ...

  9. 用算符优先法对算术表达式求值(六)

    18.11.23 这是一道最近刚上的实验课的题目.... 基于C语言,欢迎指正 实验要求 掌握栈在解决实际问题中的应用,设计一个程序,演算用算符优先法对算术表达式求值的过程,利用算符优先关系,实现对算 ...

最新文章

  1. [转]WxEmojiView
  2. ebp 函数堆栈esp_对于ESP、EBP寄存器的理解
  3. Android 自定义注解(Annotation)
  4. windows下Python+Editplus windows Python开发环境
  5. C++ union 公共体
  6. TokuDB存储引擎
  7. [转载] 康威的人生游戏与轻量级模式
  8. linux版本信息i686,i686 linux gnu
  9. python集成Bartender的雏形
  10. 进化算法——反向学习
  11. 跨平台APP----对Cordova,APPCan,DCloud,APICloud四大平台的分析(系列二)
  12. 学习笔记 C++ 动态数组类的声明
  13. 浏览器页面渲染机制-前端原理剖析
  14. 如何打造一份优秀的技术简历
  15. 使用directives进行拖拽
  16. Android HashTable
  17. R语言主成分分析PCA谱分解、奇异值分解预测分析运动员表现数据和降维可视化
  18. python 怎么算l2范数_向量范数与矩阵范数(L0, L1, L2)
  19. Python 框架 之 Django MVT 下的 M 的 模型的简单介绍和使用
  20. 现在最流行的Java开发技术是什么?

热门文章

  1. 创业圈的钱都去哪儿了?AI算法正帮Facebook成为大赢家
  2. 本想搞清楚ESM和CJS模块的互相转换问题,没想到写完我的问题更多了
  3. 数据挖掘(六)——模型优化与评估方法
  4. md5加密以及可逆的加密解密算法
  5. 我学习编程的好的学习方法!
  6. Impala服务:unable to find SASL plugin: PLAIN
  7. Data Abort产生的原因
  8. GOM登录器配置免费生成图文教程
  9. 前端-JS基础之运算符
  10. php使用aws的sns服务初探(主要是短信服务)