p; op--;
}
op--;
i++;
break;
}
default:
{
printf("传入表达式不符合要求\n");
exit(0);
}
}
}
}
while (op != 0)
{
num[j] = opera[op-1]; /* 将运算符栈中的元素依次入栈到后缀表达式栈中 */
j++;
op--;
}
num[j] = '\0';
i = 0;
while (num[i] != '\0') /* 将后缀表达式存储到传入的形参ss中 */
{
ss[i] = num[i];
i++;
}
ss[i] = '\0';
}
/* Function: 入运算符栈*/
void PushOperation(char *opera, char *ss, int *op, int *s)
{
opera[*op] = ss[*s];
(*op)++;
(*s)++;
}
完成了中缀表达式转后缀表达式,接下来就是后缀表达式的计算了,后缀表达式的计算比中缀转后缀要稍微简单一点,只需要对我们转换好的后缀表达式从左往右依次扫描,并依次入栈就行了,
意思是只需要用一个数组(double num[100])就OK了
需要考虑的情况如下
1、如果是数字,那么直接入栈到num中
2、如果是运算符,将栈顶的两个数字出栈(因为我们考虑的运算符加、减、乘、除都是双目运算符,只需要两个操作数),出栈后对两个数字进行相应的运算,并将运算结果入栈
3、直到遇到'\0'
下面用几张图,来直观了解下这个过程,以上面转换好的后缀表达式"123+*"为例(这里用ss来存储后缀表达式,num来存储计算结果,注意不要与上面图中num搞混淆了)
(注意:这里将计算结果5入栈后,栈顶从之前的[3]变成[2])
到这里后缀表达式的计算就结束了,下面附上实现代码
#include <stdio.h>
#include <stdlib.h>
#define MAX 100
void JudgeFopen_s(errno_t err); /* 判断文件打开是否成功 */
void ReadFile(FILE *fp, char *ss); /* 读取文件内容 */
double TransformCtoD(char ch); /* 将char类型数组的每一个元素转换为double */
void CalculateAndPush(double *num, int *i, int *j, char mm); /* 计算结果并入栈 */
int main()
{
FILE *fp;
errno_t err;
char ss[MAX]; /* 存储逆波兰表达式 */
int i = 0;
int j = 0;
double num[MAX]; /* 栈 */
err = fopen_s(&fp, "E:\\ww.txt", "r");
JudgeFopen_s(err); /* 判断文件打开是否成功 */
ReadFile(fp, ss); /* 读取文件内容,存储到ss中*/
while (ss[i] != '\0')
{
if (ss[i] >= '0' && ss[i] <= '9') /* 如果是数字 */
{
/* 因为num是char类型的,需要转换为double类型方便计算 */
num[j] = TransformCtoD(ss[i]); /* 将数字存储到栈中 */
j++;
i++;
}
else if (ss[i] == '+' || ss[i] == '-' || ss[i] == '*' || ss[i] == '/')
{
&nb