表达式求值--数据结构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. 编程语言系统一般都内置了对算术表达式的处理,但是他们是如何在内部实现的呢?为了 ...
随机推荐
- D - D 分糖果HDU - 1059(完全背包+二进制优化)
有两个小朋友想要平分一大堆糖果,但他们不知道如何平分需要你的帮助,由于没有spj我们只需回答能否平分即可. 糖果大小有6种分别是1.2.3.4.5.6,每种若干颗,现在需要知道能不能将这些糖果分成等额 ...
- STM32F103ZET6系统定时器SysTick
1.系统定时器SysTick的简介 系统定时器SysTick属于内核外设,内嵌在NVIC中.SysTick是一个24位的向下递减的计数器,计数器根据SysTick的时钟源计数,当SysTick的计数器 ...
- Mongo日期
当通过mongo shell来插入日期类型数据时,使用new Date()和使用Date()是不一样的: > db.tianyc04.insert({mark:, mark_time:new D ...
- centos 64位安装jpeg-6b
先安装libtool和libtool-ltdl-devel 用find命令查找config.sub和config.guess文件 find / -name config.sub find / -nam ...
- 【php】COOKIE和SESSION
一. COOKIE(小甜点,小饼干) a) 生活中的实例: i. 大保健的会员卡(记录你的姓名.性别.ID号码.手机号……) ii. 超市的会员卡(记录你的姓名,性别,会员积分) b) PHP当中的实 ...
- Linux配置dhcp服务器
一.安装dhcp软件 yum -y install dhcp 二.配置 dhcp 主配置文件 /etc/dhcp/dhcpd.conf ns-update-style interim; log-fac ...
- centos7安装puppet详细教程(简单易懂,小白也可以看懂的教程)
简介: Puppet是一种linux.unix平台的集中配置管理系统,使用ruby语言,可配置文件.用户.cron任务.软件包.系统服务等.Puppet把这些系统实体称之为资源,它的设计目标是简化对这 ...
- python3(二)
# 布尔值和Java一样不做验证了 # 空值None是一个特殊的空值 # 变量 变量名必须是大小写英文.数字和_的组合,且不能用数字开头,等号=是赋值语句,可以把任意数据类型赋值给变量,同一个变量可以 ...
- ln -s 软链接命令
所有对软链接link_name的操作都是对目录或文件dir_file的操作 ln -s [dir_file] [link_name]
- 如何利用 githob 上传自己的网站
如何搭建自己的网页是每个学前端伙伴不可缺少的一个过程,特意去看过很多如何搭建的教程,但都看不懂觉得很麻烦, 在慢慢的学习中接触到githob,发现了一个大宝藏(如果一个code都不认识githob 那 ...