//表达式求值基本思路:
//第一步:中缀表达式转后缀表达式即逆波兰表达式
/*规则: 从左到右遍历中缀表达式的每个数字和符号,若是数字就输出,即成为后
缀表达式的一部分;若是符号,则判断其与栈顶符号的优先级,是右括号或优先级低
于栈顶符号(乘除优先加减)则栈顶元素依次出栈并输出,并将当前符号进栈,一直
到最终输出后缀表达式为止。
*/
//第二步:进行逆波兰表达式求值
/*
规则: 从左到右遍历表达式的每个数字和符号,遇到是数字就进栈,遇到是符
号,就将处于栈顶两个数字出栈,进行运算,运算结果进栈,一直到最终获得结果。
*/
//详解见大话数据结构
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#define STACK_INIT_SIZE 20
#define STACKINCREMENT 10
#define MAXBUFFER 30
typedef double ElemType;
typedef char ElemType1;
char str[MAXBUFFER];
char operation[MAXBUFFER];
int prior[50];
typedef struct
{
ElemType *base;
ElemType *top;
int stacksize;
}SqStack;
typedef struct
{
ElemType1 *base;
ElemType1 *top;
int stacksize;
}SqStack1;
SqStack s;
SqStack1 Symble;
InitStack(SqStack &S)
{
S.base=(ElemType *)malloc(STACK_INIT_SIZE*sizeof(ElemType));
if (!S.base)
{
exit(0);
}
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
}
Push(SqStack &S,ElemType e)
{
if (S.top-S.base>=S.stacksize)
{
S.base=(ElemType *)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(ElemType));
if (!S.base)
{
exit(0);
}
S.top=S.base+S.stacksize;
S.stacksize+=STACKINCREMENT;
}
*S.top++=e;
}
int Pop(SqStack &S,ElemType &e)
{
if (S.top==S.base)
{
return -1;
}
else
{
e=*(--S.top);
return 0;
}
}
InitStack1(SqStack1 &S)
{
S.base=(ElemType1 *)malloc(STACK_INIT_SIZE*sizeof(ElemType1));
if (!S.base)
{
exit(0);
}
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
}
Push1(SqStack1 &S,ElemType1 e)
{
if (S.top-S.base>=S.stacksize)
{
S.base=(ElemType1 *)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(ElemType1));
if (!S.base)
{
exit(0);
}
S.top=S.base+S.stacksize;
S.stacksize+=STACKINCREMENT;
}
*S.top++=e;
}
int Pop1(SqStack1 &S,ElemType1 &e)
{
if (S.top==S.base)
{
return -1;
}
else
{
e=*(--S.top);
return 0;
}
}
char GetTopElem1(SqStack1 S)
{
if (S.top==S.base)
return '\0';
else
return *(S.top-1);
}
void priorarray() //优先级数组
{
prior[0]=-1; //空栈
prior[40]=0; //左括号
prior[43]=1; //加号
prior[45]=1; //减号
prior[42]=2; //乘号
prior[47]=2; //除号
}
int Prior(char str1,char str2) //获取优先级,
{
if (prior[str1]>=prior[str2])
{
return 1;
}
else
return 0;
}
void MidToBack(char* operation) //中缀表达式转后缀表达式
{
int i=0;
char e;
while(*operation!='\0')
{
if(isdigit(*operation)||*operation=='.')//如果是数字就输出
{
str[i++]=*operation;
if (!isdigit(*(operation+1))&&*(operation+1)!='.')
{
str[i++]=' ';//数字和数字,数字和运算符之间用空格隔离,便于解析
}
}
else //否则进行栈操作
{
switch(*operation)
{
case '-':
case '+':
case '*':
case '/':
if(Prior(*operation,GetTopElem1(Symble)))//如果优先级高于栈顶元素
{
Push1(Symble,*operation); //则入栈
}
else
{
while (GetTopElem1(Symble)!='('&&GetTopElem1(Symble)!=0)
{
Pop1(Symble,e); //如果低于栈顶元素,则栈顶元素依次出栈,知道栈为空,或栈顶元素为左括号
str[i++]=e;
}
Push1(Symble,*operation);//将本次运算符进栈
}
break;
case '(': //直接进栈
Push1(Symble,*operation);
break;
case ')': //消括号
while (GetTopElem1(Symble)!='(')
{
Pop1(Symble,e);
str[i++]=e;
}
Pop1(Symble,e);
break;
}
}
operation++;
}
while (GetTopElem1(Symble)!=0) //栈顶元素全部出栈
{
Pop1(Symble,e);
str[i++]=e;
}
str[i]='\0';
}
int Cal(char *operation,double *final) //逆波兰表达式求值
{
char temp[11];
int i=0;
double d,e;
while (*operation!='\0')
{
if(isdigit(*operation)||*operation=='.')
{
temp[i++]=*operation;
if (i>=10)
{
printf("出错:输入的单个数据过大!\n");
exit(1);
}
}
else if (*operation==' ') //字符串转浮点
{
temp[i]='\0';
d=atof(temp);
Push(s,d);
i=0;
}
else
switch(*operation)
{
case '+':
Pop(s,e);
Pop(s,d);
Push(s,d+e);
break;
case '-':
Pop(s,e);
Pop(s,d);
Push(s,d-e);
break;
case '*':
Pop(s,e);
Pop(s,d);
Push(s,d*e);
break;
case '/':
Pop(s,e);
Pop(s,d);
if (e!=0)
{
Push(s,d/e);
}
else
{
printf("\n出错:除数为零!\n");
return -1;
}
break;
}
operation++;
}
Pop(s,d);
*final=d;
}
int main()
{
double final;
InitStack1(Symble); //初始化运算符栈
InitStack(s); //初始化数字栈
printf("请输入表达式\n");
scanf("%s",operation);
priorarray(); //初始化优先级数组
MidToBack(operation); //调用中转后
Cal(str,&final);//逆波兰求值
printf("\n最终的计算结果为:%f\n",final);
return 0;
}
<img src="https://img-blog.csdn.net/20140903112457414?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvU3VuMTk5MTAxMTQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />