这篇博客介绍的表达式求值是用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. 1000行MySQL学习笔记,不怕你不会,就怕你不学!

    Windows服务 -- 启动MySQL net start mysql-- 创建Windows服务 sc create mysql binPath= mysqld_bin_path(注意:等号与值之

  2. Linux操作系统及调用接口

    Linux操作系统包含以下各子系统: 系统调用子系统:操作系统的功能调用同一入口: 进程管理子系统:对执行程序进行生命周期和资源管理: 内存管理子系统:对系统的内存进行管理.分配.回收.隔离: 文件子 ...

  3. JavaScript基本数据类型及其转换规则

    ECMAScript 数据类型 ECMAScript中有五种基本数据类型:Undefined, Null, Boolean, Number, String 一种复杂数据类型:Object 数据类型检测 ...

  4. python开发基于SMTP协议的邮件代发服务

    写在这篇文章前照例给大家灌输点名词解释,理论知识,当然已经很熟悉的同学可以往下翻直接看干货 1. 什么是SMTP SMTP即简单传输协议(Simple Mail Transfer Protocol), ...

  5. Scratch 第1课 让小猫动起来

    素材下载 链接:https://pan.baidu.com/s/1qX0T2B_zczcLaCCpiRrsnA提取码:xfp8

  6. 【数据库】MySQL数据库(三)

    一.MySQL当中的索引: 数组当中我们见过索引:它的好处就是能够快速的通过下标.索引将一个信息查到:或者说 能够快速的定位到一个信息: 1.MySQL中的索引是什么? 它是将我们表中具有索引的那个字 ...

  7. "着重内容"组件:<strong> —— 快应用组件库H-UI

     <import name="strong" src="../Common/ui/h-ui/text/c_tag_b"></import&g ...

  8. "html富文本"组件:<richtext> —— 快应用原生组件

        <template> <div class="container-full"> <richtext type="html&q ...

  9. Redis对象——有序集合(ZSet)

    有序集合类型 (Sorted Set或ZSet) 相比于集合类型多了一个排序属性 score(分值),对于有序集合 ZSet 来说,每个存储元素相当于有两个值组成的,一个是有序结合的元素值,一个是排序 ...

  10. Java 泛型、通配符? 解惑

    Java 泛型通配符?解惑 分类: JAVA 2014-05-05 15:53 2799人阅读 评论(4) 收藏 举报 泛型通配符上界下界无界 目录(?)[+] 转自:http://www.linux ...