算术表达式求值(顺序栈实现)

来源:互联网 发布:mac卸载qq输入法 编辑:程序博客网 时间:2024/05/16 19:07

一.问题描述

应用栈计算算术表达式的值。可计算:+,-,*,/。表达式中可以包括括号。

二.代码简述

定义两个栈分别用于存储操作符和操作数;

栈所具有的功能有:置栈空,判栈空,入栈,出栈,取栈顶;

将输入的算术表达式存入字符数组中;

将表达式中的运算符划分优先级;

进行双目运算,即+,-,*,/;

将表达式压入栈中,并计算表达式结果。(思路:将操作符压入操作符栈中,将操作数压入操作数栈中。过程:判断当前运算符与操作符栈栈顶元素的优先级,如果高于栈顶元素,则入栈;小于栈顶元素,则从操作数栈中依次出两个数,并将操作符栈中栈顶元素出栈,再将从操作数栈中出的两个数,按从操作符栈栈中出的运算符运算,并将结果压入操作数栈中,再将当前的操作符压入操作符栈中。

三.源代码

#include <stdio.h>#include <stdlib.h>#define MAXSIZE1 100#define MAXSIZE2 100 typedef struct{char date[MAXSIZE1];int top;}OptrStack;//操作符结构体typedef struct{double date[MAXSIZE2];int top;}OpndStack;//操作数结构体/*-------操作符相关操作-------*/OptrStack *Init_OptrStack();/*置栈空*/int Empty_OptrStack(OptrStack *s);/*判空栈*/int Push_OptrStack(OptrStack *s, char x);/*入栈(注意:判断栈是否已满)*/char Pop_OptrStack(OptrStack *s);/*出栈(注意:判断栈是否已空)*/char GetTop_OptrStack(OptrStack *s);/*取栈顶元素,先判空*//*-------操作数相关操作-------*/OpndStack *Init_OpndStack();/*置栈空*/int Empty_OpndStack(OpndStack *t);/*判空栈*/int Push_OpndStack(OpndStack *t, double y);/*入栈(注意:判断栈是否已满)*/double Pop_OpndStack(OpndStack *t);/*出栈(注意:判断栈是否已空)*/double GetTop_OpndStack(OpndStack *t);/*取栈顶元素*/int Rank(char op);//划分运算符的优先级double Operate(double a, double b, char op);//运算操作void Handle_str(char str[]);//将储存表达式的字符数组压入栈内,并运算main(){char str[100];printf("请输入算术表达式(功能:+,-,*,/。可带括号!):\n");scanf("%s", str);Handle_str(str);}/*-------操作符相关操作-------*/OptrStack *Init_OptrStack()/*置栈空*/{OptrStack *s;s = (OptrStack *)malloc(sizeof(OptrStack));s->top = -1;return s;}int Empty_OptrStack(OptrStack *s)/*判空栈*/{if(s->top == -1){return 1;//如果栈为空,则返回真数}else{return 0;//反之,返回零}}int Push_OptrStack(OptrStack *s, char x)/*入栈(注意:判断栈是否已满)*/{if(s->top == MAXSIZE1 - 1){return 0;}else{s->top ++;//栈顶指针向上移,再赋值s->date[s->top] = x;return 1;}}char Pop_OptrStack(OptrStack *s)/*出栈(注意:判断栈是否已空)*/{int x;//接收要出栈的元素if( Empty_OptrStack(s) ){return 0;}x = s->date[s->top];s->top --;return x;}char GetTop_OptrStack(OptrStack *s)/*取栈顶元素,先判空*/{if( Empty_OptrStack(s) ){return 0;}else{return (s->date[s->top]);}}/*-------操作数相关操作-------*/OpndStack *Init_OpndStack()/*置栈空*/{OpndStack *t;t = (OpndStack *)malloc(sizeof(OpndStack));t->top = -1;return t;}int Empty_OpndStack(OpndStack *t)/*判空栈*/{if(t->top == -1){return 1;}else{return 0;}}int Push_OpndStack(OpndStack *t, double y)/*入栈(注意:判断栈是否已满)*/{if(t->top == MAXSIZE2 - 1){return 0;}else{t->top ++;t->date[t->top] = y;return 1;}}double Pop_OpndStack(OpndStack *t)/*出栈(注意:判断栈是否已空)*/{double y;//接收要出栈的元素if( Empty_OpndStack(t) ){return 0;}y = t->date[t->top];t->top --;return y;}double GetTop_OpndStack(OpndStack *t)/*取栈顶元素*/{if( Empty_OpndStack(t) ){return 0;}else{return (t->date[t->top]);}}int Rank(char op)//划分运算符的优先级{int x;switch(op){case '#':x = 0;break;case '(':x = 1;break;case '+':case '-':x = 2;break;case '*':case '/':x = 3;break;}return x;}double Operate(double a, double b, char op)//运算操作{double c;switch(op){case '+':c = a + b;break;case '-':c = a - b;break;case '*':c = a * b;break;case '/':if(b == 0){printf("分母为零!\n");return 0;}elsec = a / b;break;default: printf("输入的字符非法!\n");break;}return c;}void Handle_str(char str[])//将储存表达式的字符数组压入栈内{OptrStack *optr = Init_OptrStack();//初始化操作符栈OpndStack *opnd = Init_OpndStack();//初始化操作数栈int i,j;//i,j为循环变量,a,b接收从操作数栈中出栈的元素double f,a,b;//接收将字符数转换为浮点数的值char d[100];//储存字符串中连续的‘数’char op;//接收从操作符栈中出栈的元素Push_OptrStack(optr, '#');//先往操作符栈中压入'#'for ( i = 0; str[i]; i++){switch(str[i]){case '+':case '-':/*先判断当前运算符与操作符栈栈顶元素的优先级,如果高于栈顶元素,则入栈;小于栈顶元素,则从操作数栈中依次出两个数,并将操作符栈中栈顶元素出栈,再将从操作数栈中出的两个数,按从操作符栈栈中出的运算符运算,并将结果压入操作数栈中,再将当前的操作符压入操作符栈中。*/if(GetTop_OptrStack(optr) == '#' || GetTop_OptrStack(optr) == '('){Push_OptrStack(optr, str[i]);}else{a = Pop_OpndStack(opnd);//接收从操作数栈中出栈的元素b = Pop_OpndStack(opnd);//接收从操作数栈中出栈的元素op = Pop_OptrStack(optr);//接收从操作符栈中出栈的元素Push_OpndStack(opnd, Operate(b, a, op));//将计算后的值压入操作数栈中Push_OptrStack(optr, str[i]);}break;case '*':case '/':if(Rank(str[i]) > Rank(GetTop_OptrStack(optr)) || GetTop_OptrStack(optr) == '('){Push_OptrStack(optr, str[i]);}else{a = Pop_OpndStack(opnd);b = Pop_OpndStack(opnd);op = Pop_OptrStack(optr);Push_OpndStack(opnd, Operate(b, a, op));//将计算后的值压入操作数栈中Push_OptrStack(optr, str[i]);}break;case '(':Push_OptrStack(optr, str[i]);break;case ')':while(GetTop_OptrStack(optr) != '('){a = Pop_OpndStack(opnd);b = Pop_OpndStack(opnd);op = Pop_OptrStack(optr);Push_OpndStack(opnd, Operate(b, a, op)); //将计算后的值压入操作数栈中}Pop_OptrStack(optr);break;default:j=0;do{d[j++]=str[i];i++;}while(str[i]>='0' && str[i]<='9'|| str[i]=='.');  //可存入一个或多个数字字符d[j]='\0';     //将输入的连续多个数字字符拼成了字符串i--;f=atof(d);//调用库函数atoi()将字符数转换为浮点数Push_OpndStack(opnd, f);//将转换后的数压入操作数栈中break;}}while(GetTop_OptrStack(optr) != '#'){a = Pop_OpndStack(opnd);b = Pop_OpndStack(opnd);op = Pop_OptrStack(optr);Push_OpndStack(opnd, Operate(b, a, op));//将计算后的值压入操作数栈中}printf("表达式%s = %g\n", str, GetTop_OpndStack(opnd));//将操作数栈中的元素(即表达式的最终结果)打印出来}

代码看起来有点乱,请大家介意。

0 0
原创粉丝点击