这篇博客介绍的表达式求值是用C语言实现的,只使用了c++里面的引用。

数据结构课本上的一个例题,但是看起来很简单,实现却遇到了很多问题。

这个题需要构建两个栈,一个用来存储运算符OPTR, 一个用来存储数字OPND。

但是,数字和运算符都定义成字符型栈吗?

出现了问题,当运算结果或中间结果为负时,没有办法存储。而且只能运算0~9之间的数字结果也只能是0~9之间。

那就运算符栈为字符栈, 数字栈为数值型栈,在存储时将表达式中的字符转化成数值进行存储。

但是,如果我们不用c++里面的stack进行栈的定义,而是用C语言进行实现,这种方法实现起来好像也没有这么简单,代码很多。两种栈的元素类型不一样,操作很繁琐。

怎么办呢, 我想可以用char类型的ASCII码数值来表示数值,两个栈都定义为字符栈。

数值进行存储时,将读入的字符型变量值减去0的ASCII码值  c - '0' ,然后压栈。

但这样做也有缺陷,应为C语言中char类型只有8位, 那这种方法实现的表达式求值,其结果和中间值的取值范围[ -128, 127] 。

我们主要是学习栈的实现和应用,其实对于这个题来说已经足够了。

下面附上代码的实现:

 #include <stdio.h>
#include <stdlib.h> #define ElemType char
#define STACKINCEMENT 10
#define STACK_INIT_SIZE 50 #define Status int
#define OK 1
#define ERROR 0
#define OVERFLOW -2 typedef struct{
ElemType *base;
ElemType *top;
int stacksize;
}SqStack; Status InitStack(SqStack &S){
S.top = S.base = (ElemType *)malloc(sizeof(ElemType) * STACK_INIT_SIZE);
if(!S.top)
exit(OVERFLOW);
S.stacksize = STACK_INIT_SIZE;
return OK;
}//InitStack Status Push(SqStack &S, ElemType e){
if(S.top - S.base == S.stacksize){
S.base = (ElemType *)realloc(S.base, sizeof(ElemType) *
(S.stacksize + STACKINCEMENT));
if(!S.base) exit(OVERFLOW);
S.top = S.base + S.stacksize;
S.stacksize += STACKINCEMENT;
}
*S.top++ = e;
return OK;
}//Push Status Pop(SqStack &S, ElemType &e){
if(S.base == S.top) return ERROR; e = *--S.top;
return OK;
}//Pop ElemType GetTop(SqStack S){
if(S.base == S.top) return ERROR;
return *--S.top;
}//GetTop Status In(ElemType c){
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='#'||c=='('||c==')'||c=='['||c==']')
return ;
else
return ;
}//In char Precede(ElemType a, ElemType b){
if(a=='+'||a=='-'){
if(b=='+'||b=='-'||b=='>'||b=='#'||b==')'||b==']')
return '>';
else return '<';
}
if(a=='*'||a=='/'){
if(b=='('||b=='[')
return '<';
else return '>';
}
if(a=='('){
if(b==')')
return '=';
else return '<';
}
if(a=='['){
if(b==']')
return '=';
else return '<';
}
if(a=='#'){
if(b=='#')
return '=';
else return '<';
}
}//Precede ElemType Operate(ElemType a, ElemType x, ElemType b){
switch (x){
case '+':
return a + b;
case '-':
return a - b;
case '*':
return a * b;
case '/':
return a / b;
}
}//Operator ElemType EvaluateExpression(){
SqStack OPTR, OPND;
InitStack(OPTR); //操作符
Push(OPTR, '#');
InitStack(OPND); //操作数 char x, c[];
gets(c);
int i=;
while(c[i] != '#' || GetTop(OPTR)!='#'){
if(!In(c[i])) {
if(i> && (c[i-]>''&& c[i-]<='')){
Pop(OPND, x);
Push(OPND, *x + c[i] - '');
}
else Push(OPND, c[i] - '');
i++;
}
else
switch(Precede(GetTop(OPTR), c[i])){
case '<':
Push(OPTR, c[i]);
i++;
break;
case '=':
Pop(OPTR, x);
i++;
break;
case '>':
Pop(OPTR, x);
ElemType a, b;
Pop(OPND, b); Pop(OPND, a);
Push(OPND, Operate(a, x, b));
break;
}
}
return GetTop(OPND);
}//EvaluateExpression int main(){
SqStack S;
InitStack(S);
printf("%d",EvaluateExpression()); return ;
}

表达式求值--数据结构C语言算法实现的更多相关文章

  1. 数据结构课程设计四则运算表达式求值(C语言版)

    本系统为四则运算表达式求值系统,用于带小括号的一定范围内正负数的四则运算标准(中缀)表达式的求值.注意事项:    1.请保证输入的四则表达式的合法性.输入的中缀表达式中只能含有英文符号"+ ...

  2. 数据结构算法C语言实现(八)--- 3.2栈的应用举例:迷宫求解与表达式求值

    一.简介 迷宫求解:类似图的DFS.具体的算法思路可以参考书上的50.51页,不过书上只说了粗略的算法,实现起来还是有很多细节需要注意.大多数只是给了个抽象的名字,甚至参数类型,返回值也没说的很清楚, ...

  3. C++表达式求值(利用数据结构栈)

    唉,刚刚用C++又又一次写了一个较完好的表达式求值程序,最后精简后程序还不到100行.这不经让我 想到了大一上学期刚学c语言时自己费了好大的劲,写了几百行并且功能还不是非常齐全(当时还不能计算有括号的 ...

  4. C语言中缀表达式求值(综合)

    题前需要了解的:中缀.后缀表达式是什么?(不知道你们知不知道,反正我当时不知道,搜的百度) 基本思路:先把输入的中缀表达式→后缀表达式→进行计算得出结果 栈:"先进先出,先进后出" ...

  5. 利用栈实现算术表达式求值(Java语言描述)

    利用栈实现算术表达式求值(Java语言描述) 算术表达式求值是栈的典型应用,自己写栈,实现Java栈算术表达式求值,涉及栈,编译原理方面的知识.声明:部分代码参考自茫茫大海的专栏. 链栈的实现: pa ...

  6. 【算法】E.W.Dijkstra算术表达式求值

    算术表达式求值 我们要学习的一个栈的用例同时也是展示泛型的应用的一个经典例子,就是用来计算算术表达式的值,例如 ( 1 + ( ( 2 + 3 ) * ( 4 * 5 ) ) ) 如果将4乘以5,把3 ...

  7. C/C++ 语言中的表达式求值(原文作者:裘宗燕)

    经常可以在一些讨论组里看到下面的提问:“谁知道下面C语句给n赋什么值?”m = 1; n = m+++m++;最近有位不相识的朋友发email给我,问为什么在某个C++系统里,下面表达式打印出两个4, ...

  8. Dijkstra的双栈算术表达式求值算法

    这次来复习一下Dijkstra的双栈算术表达式求值算法,其实这就是一个计算器的实现,但是这里用到了不一样的算法,同时复习了栈. 主体思想就是将每次输入的字符和数字分别存储在两个栈中.每遇到一个单次结束 ...

  9. 算法手记(2)Dijkstra双栈算术表达式求值算法

    这两天看到的内容是关于栈和队列,在栈的模块发现了Dijkstra双栈算术表达式求值算法,可以用来实现计算器类型的app. 编程语言系统一般都内置了对算术表达式的处理,但是他们是如何在内部实现的呢?为了 ...

随机推荐

  1. 1047: 【入门】正整数N转换成一个二进制数

    1047: [入门]正整数N转换成一个二进制数 时间限制: 1 Sec 内存限制: 16 MB 提交: 9786 解决: 6447 [提交] [状态] [讨论版] [命题人:外部导入] 题目描述 输入 ...

  2. js中常见的数据加密与解密的方法

    加密在我们前端的开发中也是经常遇见的.本文只把我们常用的加密方法进行总结.不去纠结加密的具体实现方式(密码学,太庞大了). 常见的加密方式 常见的加密算法基本分为这几类, 线性散列算法(签名算法)MD ...

  3. Spring IOC/ AOP 笔记

    扫描 Bean 以下主要是使用基于注解方式配置 组件扫描(一般用于自己写的类) 添加 @Component 注解,被扫描到后自动作为 Bean 组件 @ComponentScan 扫描配置的位置,将添 ...

  4. 微信小程序引入腾讯地图API方法

    微信小程序大热,在小程序过程中,我们很多时候都会用到地图.不管是企业的地址,还是商家的配送都会用到地图: 我在刚写地图这一块时,在网上也参考了很多网友的方法,始终有Bug(类似于地图拖拽是画面抖动,无 ...

  5. javascript入门 之 zTree(十一 托拽事件(一))

    <!DOCTYPE html> <HTML> <HEAD> <TITLE> ZTREE DEMO - drag & drop</TITLE ...

  6. Vue-router 第5节 vue-router利用url传递参数

    Vue-router 第5节 vue-router利用url传递参数 目录 Vue-router 第5节 vue-router利用url传递参数 第5节 vue-router利用url传递参数 冒号的 ...

  7. pgsql中的lateral使用小结

    pgsql中的lateral 什么是LATERAL 带有LATERAL的SQL的计算步骤 LATERAL在OUTER JOIN中的使用限制(或定义限制) LATERAL的几个简单的例子 总结 举几个我 ...

  8. 自己模拟的ftl 用法:

    基类 public class Ftl_object_data_model { //三种基本属性 private boolean canRead=true;//是否能读取 ;//长度 private ...

  9. Arthas-Java的线上问题定位工具

    Arthas(阿尔萨斯) 能为你做什么? Arthas 是Alibaba开源的Java诊断工具,深受开发者喜爱. 当你遇到以下类似问题而束手无策时,Arthas可以帮助你解决: 这个类从哪个 jar ...

  10. webWMS开发过程记录(四)- 整体设计

    分层 View(Servlet/Action/JSP)--> Service(接口/实现类) --> Dao(接口/实现类) 所用技术 Struts2 Hibernate Spring J ...