表达式求值--数据结构C语言算法实现
这篇博客介绍的表达式求值是用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语言算法实现的更多相关文章
- 数据结构课程设计四则运算表达式求值(C语言版)
本系统为四则运算表达式求值系统,用于带小括号的一定范围内正负数的四则运算标准(中缀)表达式的求值.注意事项: 1.请保证输入的四则表达式的合法性.输入的中缀表达式中只能含有英文符号"+ ...
- 数据结构算法C语言实现(八)--- 3.2栈的应用举例:迷宫求解与表达式求值
一.简介 迷宫求解:类似图的DFS.具体的算法思路可以参考书上的50.51页,不过书上只说了粗略的算法,实现起来还是有很多细节需要注意.大多数只是给了个抽象的名字,甚至参数类型,返回值也没说的很清楚, ...
- C++表达式求值(利用数据结构栈)
唉,刚刚用C++又又一次写了一个较完好的表达式求值程序,最后精简后程序还不到100行.这不经让我 想到了大一上学期刚学c语言时自己费了好大的劲,写了几百行并且功能还不是非常齐全(当时还不能计算有括号的 ...
- C语言中缀表达式求值(综合)
题前需要了解的:中缀.后缀表达式是什么?(不知道你们知不知道,反正我当时不知道,搜的百度) 基本思路:先把输入的中缀表达式→后缀表达式→进行计算得出结果 栈:"先进先出,先进后出" ...
- 利用栈实现算术表达式求值(Java语言描述)
利用栈实现算术表达式求值(Java语言描述) 算术表达式求值是栈的典型应用,自己写栈,实现Java栈算术表达式求值,涉及栈,编译原理方面的知识.声明:部分代码参考自茫茫大海的专栏. 链栈的实现: pa ...
- 【算法】E.W.Dijkstra算术表达式求值
算术表达式求值 我们要学习的一个栈的用例同时也是展示泛型的应用的一个经典例子,就是用来计算算术表达式的值,例如 ( 1 + ( ( 2 + 3 ) * ( 4 * 5 ) ) ) 如果将4乘以5,把3 ...
- C/C++ 语言中的表达式求值(原文作者:裘宗燕)
经常可以在一些讨论组里看到下面的提问:“谁知道下面C语句给n赋什么值?”m = 1; n = m+++m++;最近有位不相识的朋友发email给我,问为什么在某个C++系统里,下面表达式打印出两个4, ...
- Dijkstra的双栈算术表达式求值算法
这次来复习一下Dijkstra的双栈算术表达式求值算法,其实这就是一个计算器的实现,但是这里用到了不一样的算法,同时复习了栈. 主体思想就是将每次输入的字符和数字分别存储在两个栈中.每遇到一个单次结束 ...
- 算法手记(2)Dijkstra双栈算术表达式求值算法
这两天看到的内容是关于栈和队列,在栈的模块发现了Dijkstra双栈算术表达式求值算法,可以用来实现计算器类型的app. 编程语言系统一般都内置了对算术表达式的处理,但是他们是如何在内部实现的呢?为了 ...
随机推荐
- .net core 集成 sentry 进行异常报警
.net core 集成 sentry 进行异常报警 Intro Sentry 是一个实时事件日志记录和汇集的平台.其专注于错误监控以及提取一切事后处理所需信息而不依赖于麻烦的用户反馈.它分为客户端和 ...
- ACL,NAT的使用
项目练习 练习一: 练习目的:通过配置路由器的dhcp功能使pc自动获取ip地址. Router>enable Router#configure terminal Router(config) ...
- WIFI:802.11无线LAN
IEEE 802.11 无线LAN(也称WiFi) IEEE是什么 电气和电子工程师协会(IEEE,全称是Institute of Electrical and Electronics Enginee ...
- JAVA中基础类型和字串类型之间的相互转换
转自:https://www.imooc.com/code/2251 仅做个人学习记录之用,侵删. 在程序开发中,我们经常需要在基本数据类型和字符串之间进行转换. 其中,基本类型转换为字符串有三种方法 ...
- Array(数组)对象-->indexOf() 方法
1.定义和用法 indexOf() 方法可返回某个指定的字符串值在字符串中首次出现的位置,即下标. 如果没有找到匹配的字符串则返回 -1. 语法: string.indexOf(searchvalue ...
- Python zipfile模块学习
转载自https://www.j4ml.com/t/15270 import zipfile import os from zipfile import ZipFile class ZipManage ...
- SQL——语法基础篇(上)
用数据库的方式思考SQL是如何执行的 虽然 SQL 是声明式语言,我们可以像使用英语一样使用它,不过在 RDBMS(关系型数据库管理系统)中,SQL 的实现方式还是有差别的.今天我们就从数据库的角度来 ...
- 安装JDK后,未设置Path,也能执行java.exe的原因
安装JDK时,自动将java.exe复制到C:\Windows\System32下
- php+ajax实现拖动滚动条分批加载请求加载数据
HTML: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w ...
- d3限制范围缩放和平移升级到版本4
感谢您提供帮助以更新下面的代码以在版本4中工作.我已将zoom.behaviour更改为d3.zoom,但我不清楚所需的其他更改.看起来比v3还要复杂! <!DOCTYPE html> & ...