栈应用---计算表达式

来源:互联网 发布:网络主播经纪公司合同 编辑:程序博客网 时间:2024/06/05 21:09

为实现运算符优先级,可以使用两个工作栈,一个用来存操作数(opnd),另一个存操作符(optr)

基本思想是:1.首先置两个栈为空栈.依次读入表达式中的每个字符,若是操作数,则进opnd,若是运算符,则和optr栈顶元素比较,这时分三种情况

1.栈顶元素优先级低

 直接进栈

2.相等('栈顶为'(',与之想比较的操作符为')'')

出栈,(脱去左括号)

3.栈顶元素优先级大

        1.optr出栈op,得到操作符

        2opnd,出栈,s1,出栈s2,

        3.s1,s2,op,进行运算,并将结果放入opnd中

 

 

上述操作完成后,基本工作已经完成,之后,再一一取栈中元素,运算

               +        -          *          /            (         )           #

+             >        >         <         <           <        >          >          

-              >        >          <        <           <        >           > 

*             >          >         >         >          <        >          >   

/              >           >        >        >           <         >          >

(             <         <           <        <           <          =            

)            >         >             >        >                      >         >

#            <         <           <         <          <                       =

#include <stdio.h>#include <malloc.h>#include <string.h>#define NULL 0#define TRUE 1#define FALSE 0#define RIGHT 1#define DOWN  2#define LEFT  3#define UP    4const int width = 10;const int height = 10;int maze[height][width]={//0,1,2,3,4,5,6,7,8,9{1,1,1,1,1,1,1,1,1,1},//0{1,0,0,1,0,0,0,1,0,1},//1{1,0,0,1,0,0,0,1,0,1},//2{1,0,0,0,0,1,1,0,0,1},//3{1,0,1,1,1,0,0,0,0,1},//4{1,0,0,0,1,0,0,0,0,1},//5{1,0,1,0,0,0,1,0,0,1},//6{1,0,1,1,1,0,1,1,0,1},//7{1,1,0,0,0,0,0,0,0,1},//8{1,1,1,1,1,1,1,1,1,1},//9};int foot[height][width]={0};typedef struct PosType{int x;int y;}PosType;/*typedef struct {PosType pos;int di;}ElemType;*/typedef char ElemType;typedef struct{int **path;int width;int height;}MazePath;//地图MazePath mazepath = {(int **)maze,width,height}; typedef struct _stack{ElemType data;struct _stack* next;}Stack , *PStack;const int nLEN = sizeof(Stack);void InitStack(PStack* head){(*head) = (PStack)malloc(nLEN);//(*head)->data = NULL;(*head)->next = 0;}void DestroyStack(PStack *head){PStack p = *head;PStack p1 = p;while(p){p = p->next;free(p1);p1 = p;}}void CleadStack(PStack *head){PStack p = (*head)->next;PStack p1 = p;while(p){p = p->next;free(p1);p1 = p;}}int StackEmpty(PStack s){s = s->next;if(s!=NULL)return FALSE;else return TRUE;}int StackLength(PStack s){s = s->next;int nSize = 0;while(s!=NULL){nSize++;s = s->next;}return nSize;}int GetTop(PStack s,ElemType *data){if(!StackEmpty(s)){s = s->next;*data = s->data;return TRUE;}return FALSE;}int Push(PStack s,ElemType data){PStack temp = (PStack)malloc(nLEN);temp->data = data;temp->next = NULL;//temp->next = s->next;s->next = temp;return TRUE;}int Pop(PStack s,ElemType *data){if(StackEmpty(s))return FALSE;PStack temp = s->next;*data = temp->data;s->next = s->next->next;free(temp);return TRUE;}//能否通过int Canpass(PosType pos){int x = pos.x;int y = pos.y;//已经走过if(foot[y][x]==1){return FALSE;}//有障碍int (*p)[width] = (int(*)[width])(mazepath.path);if(p[y][x]==1){return FALSE;}return 1;}//留下足迹void MarkFoot(PosType pos){int x = pos.x;int y = pos.y;foot[y][x] = 1;}PosType NextPos(PosType pos,int di){PosType p;if(di==RIGHT){p.x = pos.x +1;p.y = pos.y;}else if(di == LEFT){p.x = pos.x-1;p.y = pos.y;}else if(di==DOWN){p.x = pos.x;p.y = pos.y+1;}else if(di == UP){p.x = pos.x;p.y = pos.y-1;}return p;}char Precede(char ch1,char ch2){//if(ch1 == ch2)//return '=';if(ch1==' ')return '<';if(ch1=='+'){if(ch2=='+')return '<';if(ch2=='-')return '>';if(ch2=='*')return '<';if(ch2=='/')return '<';if(ch2=='(')return '<';if(ch2==')')return '>';}else if(ch1=='-'){if(ch2=='+')return '<';if(ch2=='-')return '>';if(ch2=='*')return '<';if(ch2=='/')return '<';if(ch2=='(')return '<';if(ch2==')')return '>';}else if(ch1=='*'){if(ch2=='+')return '>';if(ch2=='-')return '>';if(ch2=='*')return '>';if(ch2=='/')return '>';if(ch2=='(')return '<';if(ch2==')')return '>';}else if(ch1=='/'){if(ch2=='+')return '>';if(ch2=='-')return '>';if(ch2=='*')return '>';if(ch2=='/')return '>';if(ch2=='(')return '<';if(ch2==')')return '>';}else if(ch1=='('){if(ch2=='+')return '<';if(ch2=='-')return '<';if(ch2=='*')return '<';if(ch2=='/')return '<';if(ch2=='(')return '<';if(ch2==')')return '=';}else if(ch1==')'){if(ch2=='+')return '>';if(ch2=='-')return '>';if(ch2=='*')return '>';if(ch2=='/')return '>';if(ch2=='(')return ' ';if(ch2==')')return '>';}}int IsNum(char ch){if(ch<='9' && ch>='0')return TRUE;return FALSE;}char calc(char a,char op,char b){if(op=='+')return a+b;if(op=='-')return a-b;if(op=='*')return a*b;if(op=='/')return a/b;}int EvalueateExpression(char *buf,int nlen){char ch=0;int i=0;PStack opnd,optr;InitStack(&opnd);//操作数InitStack(&optr);//操作符ElemType nd;ElemType tr;for(i = 0 ; i < nlen ; i++){ch = buf[i];//数字if(IsNum(ch)){nd = ch-48;Push(opnd,nd);}//操作符else{tr = ' ';GetTop(optr , &tr);char cRet = Precede(tr , ch);if(cRet =='<'){Push(optr,ch);}else if(cRet =='='){Pop(optr,&tr);}else if(cRet=='>'){char op;Pop(optr,&op);char a1,a2;Pop(opnd,&a1);Pop(opnd,&a2);char ret = calc(a2 , op , a1);Push(opnd , ret);i--;}}}while(!StackEmpty(optr)){char op;Pop(optr,&op);char a1,a2;Pop(opnd,&a1);Pop(opnd,&a2);char ret = calc(a2 , op , a1);//printf("ret = %d",ret);Push(opnd , ret);}if(!StackEmpty(opnd)){char cRet = 0;Pop(opnd,&cRet);printf("%-d\n",cRet);}return 0;}int main(){char buf[]="3*5";int nlen = strlen(buf);EvalueateExpression(buf , nlen);printf("\n");return 0;}

 

 

原创粉丝点击