表达式求值:
表达式求值:
先建立一个文件: 文件名为 stack.cpp
//头文件
#include"stdio.h"
#include"stdlib.h"
#include"malloc.h"
//宏定义
#define STACK_INIT_SIZE 100 //存储空间初始分配量
#define STACKINCREMENT 10 //存储空间分配增量
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef char SElemType;
typedef char Status;
//栈的顺序结构体
typedef struct{
SElemType *base; //在栈构造之前和销毁之后,base 的值为NULL;
SElemType *top; //栈顶指针
int stacksize; //当前已分配的存储空间,以元素为单位
}SqStack;
//------------基本操作的函数原型说明--------------
//Status InitStack(SqStack &S); //构造一个空栈S
//Status DestroyStack(SqStack &S); //销毁栈S,S不再存在
//Status ClearStack(SqStack &s); //把栈S置位空
//Status StackEmpty(SqStack S); //若栈S为空栈,则返回TRUE,否则返回FALSE
//int StackLength(SqStack S); //返回S的元素个数,即栈的长度
//Status GetTop(SqStack S,SElemType &e); //若栈不为空,则用e返回S的栈顶元素,并返回OK,否则返回ERROR
//Status Push(SqStack &S,SElemType e); //插入元素e为新的栈顶元素
//Status Pop(SqStack &S,SElemType &e); //若栈不为空,则删除S的栈顶元素,用e返回其值,并返回OK,否则返回ERROR
//Status StackTraverse(SqStack S,Status (*visit) () );
//从栈底到栈顶依次对栈中每个元素调用函数 visit() , 一旦 visit() 失败,则操作失败
//1.构建栈
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;
}
//2.销毁栈
Status DestroyStack(SqStack &S){
S.top=NULL;
S.stacksize=0;
free(S.base);
return OK;
}
//3.清空栈
Status ClearStack(SqStack &S){
S.top=S.base; //栈顶和栈底指向同一个位置,即为空
return OK;
}
//4.判断栈是否为空
Status StackEmpty( SqStack S)
{
if(S.top==S.base)
return ERROR;
else
return TRUE;
}
//5.求栈的长度
Status StackLength(SqStack S)
{
int n;
if(S.top==S.base)
return FALSE;
else{
n=S.top-S.base;
return n;
}
}
//6.求栈顶元素
Status GetTop(SqStack S,SElemType &e)
{
if(S.top==S.base)
return FALSE;
else
return ( e=*(S.top-1) );
}
//7.栈顶插入元素
Status Push(SqStack &S,SElemType &e)
{ //插入元素 e 为新的栈顶元素
if(S.top-S.base >= STACK_INIT_SIZE) //栈满的时候就需要追加存储空间
{
S.base=(SElemType *)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(SElemType));
if(!S.base) exit(OVERFLOW); //存储空间分配失败
S.top=S.base+S.stacksize; //栈底的位置可能改变,需要重新定位栈顶元素
//S.top 还是之前的那个没有存储的位置
S.stacksize = S.stacksize+STACKINCREMENT;
}
*S.top=e;
S.top++;
return OK;
}
//8.栈顶出栈元素
Status Pop(SqStack &S,SElemType &e){
//若栈不为空,则删除 S 的栈顶元素,用 e 返回其值,并返回 OK ,否则返回ERROR
if(S.top == S.base) return ERROR;
e=*(--S.top); //可以不加括号,但需要记住的是,需要让 top 指针减 1 ,再取出元素
return OK;
}
//9.遍历栈
Status StackTraverse(SqStack S){
if(S.base==NULL) return ERROR;
if(S.top==S.base){
printf("栈为空,没有元素-------!");
return FALSE;
}
SElemType *p=S.top; //先找出 top 的地址
while(p > S.base)
{
p--;
printf("%d\n",*p);
}
return OK;
}
再建一个文档,文件名为 expression.cpp
#include<stdio.h>
#include"Stack.cpp" //Stack.cpp 中包含了各种对栈的操作,直接调用就可以了
Status In(SElemType c){ //判断c是否为运算符
switch(c){
case '+':
return 1; break;
case '-':
return 1; break;
case '*':
return 1; break;
case '/':
return 1; break;
case '(':
return 1; break;
case ')':
return 1; break;
case '#':
return 1; break;
default:
return 0;
}
}
//比较两个运算符的优先级
//a,b中存放待比较的运算符
// a>b 是a的运算符 大于 b 的运算符
// 0 表示不能出现
Status Precede(SElemType a,SElemType b){
int i,j;
char table[7][7]={ //运算符的表格
// + - * / ( ) #
/* + */ {'>','>','<','<','<','>','>'},
/* - */ {'>','>','<','<','<','>','>'},
/* * */ {'>','>','>','>','<','>','>'},
/* / */ {'>','>','>','>','<','>','>'},
/* ( */ {'<','<','<','<','<','=','0'},
/* ) */ {'>','>','>','>','0','>','>'},
/* # */ {'<','<','<','<','<','0','='}
};
switch(a){
case '+': i=0; break;
case '-': i=1; break;
case '*': i=2; break;
case '/': i=3; break;
case '(': i=4; break;
case ')': i=5; break;
case '#': i=6; break;
}
switch(b){
case '+': j=0; break;
case '-': j=1; break;
case '*': j=2; break;
case '/': j=3; break;
case '(': j=4; break;
case ')': j=5; break;
case '#': j=6; break;
}
return table[i][j];
}
SElemType Operate(SElemType a,SElemType theta,SElemType b){ //计算a,b运算后的数值
int i,j,result;
i=a;
j=b;
switch(theta) {
case '+': result = i + j; break;
case '-': result = i - j; break;
case '*': result = i * j; break;
case '/': result = i / j; break;
}
return result;
}
SElemType EvaluateExpression(){
//算术表达式求值得算符优先算法,设OPTR(运算符栈) 和OPND(运算数栈)分别为 运算符栈 和 运算数栈
//OP 为运算符集合
SElemType c; //getchar 输入的
SElemType e; //获得的栈顶元素
SElemType theta; //从栈中弹出的元素
SElemType a,b; //从OPND中出栈的数字
SElemType result; //进行 Operate 操作后的结果
SElemType x;
SqStack OPTR,OPND;
InitStack(OPTR); c='#'; Push(OPTR,c);
InitStack(OPND);
c=getchar();
GetTop(OPTR,e); //获取栈顶元素
while( c!='#' || e!='#' ){
//如果不运算符,就入OPND栈, 接着获取下一个数字
if(! In(c) ){ Push(OPND,c); c=getchar(); GetTop(OPTR,e); }
else{
switch( Precede(e,c) ){ //将刚栈顶的元素与刚输入的元素进行比较
case '<': //栈顶元素的优先权低
Push(OPTR,c); //压入栈 , 读取下一个字符
c=getchar();
GetTop(OPTR,e);
break;
case '>': //栈顶元素的优先权高
Pop(OPTR,theta); //退栈并将运算结果入栈
Pop(OPND,b);
Pop(OPND,a);
result=Operate(a,theta,b);
Push(OPND,result);
GetTop(OPTR,e);
break;
case '=': //OPTR栈顶元素是 "(" 且c是 ")"
Pop(OPTR,x);
c=getchar();
GetTop(OPTR,e);
break;
} //switch
}
}//while
GetTop(OPND,e);
return e;
}
//主函数
void main(){
int EndNum;
printf("Please enter the arithmetic expression.End with #. \n");
EndNum=EvaluateExpression();
printf("The results of is : %d \n",EndNum);
}
以上代码仍不能很好实现,如有建议,敬请留言,谢谢!