数据结构与算法系列-栈-栈的应用
2013-11-10 21:51
260 查看
1:算术表达式的计算
表达式求值是编译系统中的一个基本问题,目的是把我们平时书写的算术表达式变成计算机能够理解并能正确求值的表达式。算术表达式中包含算术运算符和操作符。在运算的时候必须按优先级运算。因此,进行表达式运算时,必须设置两个栈,一个栈用于存放运算符,另外一个用于存放操作符。
大家可以看下这边文章 。利用堆栈求解算术表达式
栈的应用举例:数制转换,表达式求值 代码来自http://blog.sina.com.cn/s/blog_6f5235a10100z1b7.html
#include <stdio.h> #include <malloc.h> #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 #define OVERFLOW -2 #define STACK_INIT_SIZE 100 #define STACKINCREMENT 10 typedef char SElemType; typedef char Status; typedef struct{ SElemType *base; SElemType *top; int stacksize; }SqStack; Status InitStack(SqStack *S){ //构造一个空栈S S->base =(SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType)); if(!S->base ) exit(OVERFLOW); //存储分配失败 S->top =S->base ; S->stacksize =STACK_INIT_SIZE; return OK; } //InitStack Status GetTop(SqStack *S){ SElemType e; if(S->top==S->base ) return ERROR; e=*(S->top -1); return e; }//GetTop Status Push(SqStack *S,SElemType e){ //插入元素e为新的栈顶元素 if(S->top-S->base>=S->stacksize ) { //栈满,追加存储空间 S->base =(SElemType *)realloc (S->base ,(S->stacksize +STACKINCREMENT) * sizeof(SElemType)); if(!S->base ) exit(OVERFLOW); S->top =S->base +S->stacksize ; S->stacksize +=STACKINCREMENT; } *S->top ++=e; return OK; }//Push Status Pop(SqStack *S,SElemType *e){ //若栈不为空,则删除S的栈顶元素,用E返回其值,并返回OK;否则返回ERROR if(S->top==S->base ) return ERROR; e=--S->top ; return (*e); }//Pop Status StackEmpty(SqStack *S){ if(S->base==S->top) return TRUE; else return FALSE; }//StackEmpty SElemType Precede(SElemType i,SElemType j){ int a, b;char c; char s[7][7]={{'>','>','<','<','<','>','>'},{'>','>','<','<','<','>','>'},{'>','>','>','>','<','>','>'}, {'>','>','>','>','<','>','>'},{'<','<','<','<','<','=',' '},{'>','>','>','>',' ','>','>'},{'<','<','<','<','<',' ','='}}; //算符间优先关系 switch (i){ case '+': a=0;break; case '-': a=1;break; case '*': a=2;break; case '/': a=3;break; case '(': a=4;break; case ')': a=5;break; case '#': a=6;break; } switch (j){ case '+': b=0;break; case '-': b=1;break; case '*': b=2;break; case '/': b=3;break; case '(': b=4;break; case ')': b=5;break; case '#': b=6;break; } c=s[a][b]; return c; //返回优先级权值 } Status Operate(SElemType a,SElemType theta,SElemType b){ //求算数表达式的值 int c,x,y; switch (theta){ case '+': x=(int)a-48; //或x=(int)(a-'o') y=(int)b-48; c=x+y+48; return (char)c; break; case '-': x=(int)a-48; y=(int)b-48; c=x-y+48; return (char)c; break; case '*': x=(int)a-48; y=(int)b-48; c=x*y+48; return (char)c; break; case '/': x=(int)a-48; y=(int)b-48; c=x/y+48; return (char)c; break; } } char EvaluateExpress(){ //算数表达式求值的算符优先算法,设OPTR和OPND分别为运算符栈和运算数栈 SqStack OPTR,OPND; char c,a,b,x,theta; c=' '; InitStack(&OPTR);Push(&OPTR,'#'); InitStack(&OPND); printf("\n请输入要计算的表达式"); c=getchar(); while(c!='#'||GetTop(&OPTR)!='#'){ if(c>'0'&&c<'9'){ Push(&OPND,c);c=getchar();//不是运算符进运算数栈 } else switch(Precede(GetTop(&OPTR),c)){ case '<': //栈顶元素优先权低 Push(&OPTR,c);c=getchar(); break; case '=': //脱冒号并接收下一个字符 Pop(&OPTR,&x);c=getchar(); break; case '>': //退栈并将运算结果入栈 theta=Pop(&OPTR,&theta); b=Pop(&OPND,&b); a=Pop(&OPND,&a); Push(&OPND,Operate(a,theta,b)); break; } //switch } //while return GetTop(&OPND); } //EvaluateExpress
2:中缀表达式转换成后缀表达式
算术表达式有两种形式中缀算术表达式: 6-8/4+3*5
后缀表达式:(将运算符置于两个操作数的后面):20 10 2 3 + / 2
将中缀表达式转换成后缀表达式
(1): 将@压入运算符栈
(2)若遇到操作数 直接输出 并输入一个空格作为两个操作数的分隔符
(3)若遇到操作符 则必须与栈顶比较 运算级别比栈顶高的则进栈 否则退出栈顶元素并输出 然后输出一个空格作为分隔符
(4)若遇到左括号 进栈 若遇到右括号 则一直退栈输出, 直到退到左括号为止
(5)当栈空时 输出的结果即为后缀表达式
中缀表达式转后缀表达式C++代码
3:函数递归的实现
求阶乘int suml(int n){ if(n==0) return 1 else return (n * suml(n-1)) }
递归函数的实现
1:系统首先为递归调用建立一个工作栈,在该工作栈中存放参数、局部变量和调用后的返回地址等信息
2:在每次递归调用之前,把本次算法中所使用的参数、局部变量的当前值和调用后的返回地址等压入栈顶
3:在每次调用递归结束之后,又把栈顶元素弹出,分别赋予相应的参数和局部变量,以便使他们恢复到调用前的状态,然后返回由返回地址所指定的位置
4:继续执行后续指令
相关文章推荐
- 数据结构与算法系列-线性表-线性表的应用
- 【Hadoop入门学习系列之四】MapReduce 2.0应用场景和原理、基本架构和编程模型
- 开源组件应用系列:Log4net之基本配置(收藏)
- Struts1.x系列教程(11):Validator验证框架高级应用
- 《Redis系列专题》 之 大规模互联网应用Redis架构要点(精华)
- 全系列三极管应用参数和代换大全
- 大型网站架构系列:缓存在分布式系统中的应用(二)
- WPF 基础到企业应用系列4——WPF千年轮回
- iOS开发系列--让你的应用“动”起来,iOS动画
- iOS 9学习系列:如何使用ATS提高应用的安全性
- 在线报表设计实战系列 – ⑥矩表高级应用
- 当路町-网络下载应用系列之三-认识磁力链接Magnet URL
- 分布式缓存技术redis学习系列(四)——redis高级应用(集群搭建、集群分区原理、集群操作)
- Android应用.三星i9000系列(2).工程代码,网络锁与锁三键
- Flex2 开发中应用样式系列(1)
- TIBCO ESB实战系列:AppManage的应用
- MSSQL应用系列---NOLOCK 和ROWLOCK 的秘密
- XML应用系列:使用C#开发基于XSLT的代码生成器
- WPF地图应用开发-----BingMap系列1
- [原创]HandlerSocket系列(二):架构、特点及其应用场景