本质上是后缀表达式和中缀转后缀的结合
思路:1.遇到操作数,直接入栈
2.遇到界限符,若‘(’,入栈;若是‘)’,则是弹出操作符,直到‘(’,记得top--,把‘(’去掉
3.遇到操作符,先判空,为空,直接入栈;不为空,弹出比此运算符级别高的或者相等的运算符,每弹出一个运算符,则相对应操作数也需要弹出两个,进行运算,这里就需要判断存放操作数的栈是否含有两个及以上的操作数,若没有,直接输出错误(我这里是没有进行这个判断的),若没错,进行运算,将结果压入操作数栈,操作数栈和运算符栈都减1
4.最后需要判断运算栈是不是为-1,若不是需要再次运算。最后判断操作栈是不是只有一个元素,是则直接输出,不是则输出错误。
/*
无论是前面的中缀转后缀还是现在的中缀的计算,我认为最大的漏洞就是最后判断
两个栈为空的问题
*/
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<string.h>
#define Maxsize 10
typedef struct{ //定义一个存放操作数的栈
float data[Maxsize];
int top1;
}Sqstack1;
typedef struct{ //定义一个存放运算符的栈
char data[Maxsize];
int top2;
}Sqstack2;
void Initstack(Sqstack1 *s1, Sqstack2 *s2)// 初始化
{
s1->top1 = -1;
s2->top2 = -1;
}
void push1(Sqstack1 *s1, float x) //操作数入栈
{
s1->top1++;
s1->data[s1->top1] = x;
}
void push2(Sqstack2 *s2, char x) // 运算符入栈
{
s2->top2++;
s2->data[s2->top2] = x;
}
int zhuanhuan(char x) //将符号转化为数字
{
switch(x)
{
case '+': return 1;
case '-': return 1;
case '*': return 2;
case '/': return 2;
case '(': return 0;
}
}
void jisuan(Sqstack1 *s1, Sqstack2 *s2, char c) //对其运算
{
switch(c) //注意计算的时候先出栈的在运算符右边
{
case '+' :
s1->data[s1->top1-1] = s1->data[s1->top1-1] + s1->data[s1->top1]; s1->top1--; s2->top2--;break;
case '-' :
s1->data[s1->top1-1] = s1->data[s1->top1-1] - s1->data[s1->top1]; s1->top1--; s2->top2--;break;
case '*' :
s1->data[s1->top1-1] = s1->data[s1->top1-1] * s1->data[s1->top1]; s1->top1--; s2->top2--;break;
case '/' :
s1->data[s1->top1-1] = s1->data[s1->top1-1] / s1->data[s1->top1]; s1->top1--; s2->top2--;break;
}
}
void yunsuanfu(Sqstack1 *s1, Sqstack2 *s2, char x) //对运算符的操作
{
if(s2->top2 == -1)
push2(s2, x);
else
{
while(zhuanhuan(s2->data[s2->top2]) >= zhuanhuan(x))
{
jisuan(s1, s2, s2->data[s2->top2]);
if(s2->top2 == -1 || s2->data[s2->top2] == '(')
break;
}
push2(s2, x);
}
}
void jiexianfu(Sqstack1 *s1, Sqstack2 *s2) //处理遇到)的情况
{
while(s2->data[s2->top2] != '(')
{
jisuan(s1, s2, s2->data[s2->top2]);
}
s2->top2--;
}
int main()
{
Sqstack1 s1;
Sqstack2 s2;
Initstack(&s1, &s2);
int i;
char a[10];
printf("请输入需要计算的中缀表达式:");
scanf("%s", a);
for(i = 0; i<strlen(a); i++)
{
if(a[i] >= '0' && a[i] <= '9')
{
float x = a[i] - '0';
push1(&s1, x);
}
else if(a[i] == '+' || a[i] == '-' || a[i] == '/' || a[i] == '*')
{
yunsuanfu(&s1, &s2, a[i]);
}
else
{
if(a[i] == '(')
push2(&s2, a[i]);
if(a[i] == ')')
{
jiexianfu(&s1, &s2);
}
}
}
while(s2.top2 != -1) // 确认运算符全部出栈
{
jisuan(&s1, &s2, s2.data[s2.top2]);
}
if(s1.top1 == 0)
{
printf("%.2f\n", s1.data[s1.top1]);
}
else
{
printf("表达式错误");
}
return 0;
}