数据结构顺序栈对表达式求知算法

来源:互联网 发布:cs漫画软件 编辑:程序博客网 时间:2024/06/01 09:34

//表达式求值(输入、输出和中间结果均只能是0~9)运算符仅限+-*/。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define STACK_INIT_SIZE 80 //栈初始化时的长度
#define STACKINCREMENT 10  //栈长度的增量
#define ERROR 0
#define OK 1
typedef int Status;
typedef char SElemType;
typedef struct SqStack  //定义一个顺序栈
 {
SElemType *top;   //栈顶指针
SElemType *base;  //栈底指针
int stacksize;   //栈可用的最大长度
 }SqStack;


Status InitStack(SqStack *S)    //栈的初始化
 {
 (*S).base=(SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));
if(!(*S).base) return ERROR;
(*S).top=(*S).base;
(*S).stacksize=STACK_INIT_SIZE;
return OK;
 }


Status Push(SqStack *S,SElemType e)  //栈元素进栈函数
 {
if(((*S).base-(*S).top)>(*S).stacksize)
 {
 (*S).base=(SElemType*)realloc((*S).base,
 (STACKINCREMENT+(*S).stacksize)*sizeof(SElemType));
 (*S).top=(*S).base+(*S).stacksize;
 (*S).stacksize+=STACKINCREMENT;
 }
if(!(*S).base)
 {
 printf("FAILURE to realloc the Memory units!\n");
 exit(ERROR);
 }
 *((*S).top)++=e;
return OK;
}


Status Pop(SqStack *S,SElemType *e)  //栈元素出栈函数
 {
if(S->top==S->base)
{
 printf("栈为空!");
 exit(ERROR);
 }
else
 {
*e=*--S->top;
 }
return OK;
 }


SElemType GetTop(SqStack S)  //取栈顶元素的函数
 {
if(S.base==S.top) return ERROR;
return *(S.top-1);
 }


Status In(SElemType c) //判断C是否是操作符的函数
{
switch(c)
 {
case'+':
case'-':
case'*':
case'/':
case'(':
case')':
case'#':return OK;
break;
default:return ERROR;
 }


 }


SElemType Precede(SElemType ch1,SElemType ch2) // 判断两个运算符的优先级的函数
 {
SElemType f;
switch(ch2)
 {
case'+':
case'-': if(ch1=='('||ch1=='#')
 f='<';
else
 f='>';
break;
case'*':
case'/':if(ch1=='*'||ch1=='/'||ch1==')')
 f='>';
else
 f='<';
break;
case'(': if(ch1==')')
 {
 printf("ERROR1\n");
 exit(ERROR);
 }
else
 f='<';
break;
case')':switch(ch1)
 {
case'(':f='=';
break;
case'#':printf("ERROR2\n");
 exit(ERROR);
default: f='>';
 }
break;
case'#':switch(ch1)
 {
case'#':f='=';
break;
case'(':printf("ERROR3\n");
 exit(ERROR);
default: f='>';
 }
 }
return f;
 }


Status Operate(int a,SElemType theta,int b)
 {
int c;
switch(theta)
 {
case'+':c=a+b;
break;
case'-':c=a-b;
break;
case'*':c=a*b;
break;
case'/':c=a/b;
break;
 }
return c;
 }


SElemType EvaluateExpression()
{
//算术表达是求值的算符优先算法。设OPTR和OPND分别为运算符栈和运算数栈,
SElemType ch,x,a,b;
int c,d,e;
 SqStack OPTR,OPND;
 InitStack(&OPTR);//运算符栈的初始化
 Push(&OPTR,'#');
 InitStack(&OPND);//运算数栈的初始化
 ch=getchar();
while(ch!='#'||GetTop(OPTR)!='#')
 {
if(!In(ch)) 
 {
Push(&OPND,ch);
ch=getchar();} //不是运算符则进栈
else
 {
switch(Precede(GetTop(OPTR),ch))
 {
case'<'://栈顶元素优先级低
 Push(&OPTR,ch);
 ch=getchar();
break;
case'='://脱括号并接收下一个字符
 Pop(&OPTR,&x);
 ch=getchar();
break;
case'>'://退栈并将运算结果入栈
 Pop(&OPTR,&x);
 Pop(&OPND,&a);
 Pop(&OPND,&b);
 d=atoi(&a);
 e=atoi(&b); //用这个函数atoi()可以避免用ASCII码,
//可以将数字字符串转化为整型,但是这不是跨平台的,这是windows里面特有的函数
 c=Operate(e,x,d);
 itoa(c,&a,10);
 Push(&OPND,a); 
break;
 }
 }//else
 }//end_of_while
return GetTop(OPND);
 }//end_of_EvaluateExpression


int main()
 {
 puts("表达式求值(输入、输出和中间结果均只能是0~9)运算符仅限+-*/");
 printf("请输入算术表达式:以#结束。如9-2*4+4#\n"); 
 loop:printf("%c",EvaluateExpression()); 
 printf("\n");
 goto loop;
 return 0;
 }

0 0