这篇博客介绍的表达式求值是用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. SQL Server中STATISTICS IO物理读和逻辑读的误区

    SQL Server中STATISTICS IO物理读和逻辑读的误区 大家知道,SQL Server中可以利用下面命令查看某个语句读写IO的情况 SET STATISTICS IO ON 那么这个命令 ...

  2. PTA | 1010 一元多项式求导 (25分)

    设计函数求一元多项式的导数.(注:xn(n为整数)的一阶导数为n*xn-1.) 输入格式: 以指数递降方式输入多项式非零项系数和指数(绝对值均为不超过1000的整数).数字间以空格分隔. 输出格式: ...

  3. thinkphp中array_diff运行无效 Invalid opcode 153/1/8

    经本人查证,发现是thinkPHP优化导致的与array_diff冲突.thinkPHP 报的错:Invalid opcode 153/1/8.有谁知道原理的,说说,让俺也明白.

  4. 一分钟搞定Java高频面试题

    一分钟搞定Java高频面试题 一.变量赋值和计算 题目: public static void main(String[] args) { int i = 1; i = i++; int j = i+ ...

  5. Git常用命令(二)

    git clone + URL 获取该项目源代码 $ git log 回顾提交历史 $ git log -p -(数字) 用来显示每次提交的内容差异+(数字)表示看最近几条 $ git log --s ...

  6. 【Selenium01篇】python+selenium实现Web自动化:搭建环境,Selenium原理,定位元素以及浏览器常规操作!

    一.前言 最近问我自动化的人确实有点多,个人突发奇想:想从0开始讲解python+selenium实现Web自动化测试,请关注博客持续更新! 二.话不多说,直接开干,开始搭建自动化测试环境 这里以前在 ...

  7. Web Scraper 高级用法——使用 CouchDB 存储数据 | 简易数据分析 18

    这是简易数据分析系列的第 18 篇文章. 利用 web scraper 抓取数据的时候,大家一定会遇到一个问题:数据是乱序的.在之前的教程里,我建议大家利用 Excel 等工具对数据二次加工排序,但还 ...

  8. Linux下删除大量文件效率对比

    来自公众号:马哥Linux运维 今天我们来测试一下Linux下面删除大量文件的效率. 首先建立50万个文件 $ test   for i in $(seq 1 500000);do echo text ...

  9. hibernate.current_session_context_class 比较权威的解释

    hibernate.current_session_context_class 博客分类: hibernate HibernateSpring多线程配置管理thread  遇到过的问题: 情景1: 在 ...

  10. 【MyBatis深入剖析】应用分析与最佳实践

    ##### 文章目标1. 了解ORM框架的发展历史,了解MyBatis特性2. 掌握MyBatis编程式开发方法和核心对象3. 掌握MyBatis核心配置含义4. 掌握MyBatis的高级用法与扩展方 ...