问题描述
一个算术表达式是由操作数(operand)、运算符(operator)和括号组成的。假设操作数均是正实数,运算符只含加减乘除四种运算符。编程利用“算符优先法”求算术表达式的值。
基本要求:
(1) 从键盘或文件读入一个合法的算术表达式,输出相应的后缀表达式。后缀表达式中,数据与数据之间加分隔符;
(2) 输出正确的计算结果,保留两位小数点;
(3) 考虑算法的健壮性,当表达式错误时,要给出错误提示
(4) 可以连续输入,即输入完一个表达式,转换和计算完成后可以提示用户继续输入表达式,直到用户输入一个“#”则退出程序。
算法描述
主要用栈来实现,时间复杂度为O©。先将中缀表达式转化为后缀表达式,再对后缀表达式求值。中缀表达式转化为后缀表达式的过程与课件中类似:如果遍历到数字,将其直接放入post;如果遍历到‘(’,直接入栈;如果遍历到‘)’,弹栈,弹出的符号放入输出,一直弹到将‘(’弹出栈为止;如果遍历到的是运算符,此时如果栈是空的,或者栈顶元素是‘(’,直接将该运算符入栈;否则,如果栈顶符号的优先级别大于或者等于当前运算符,弹栈,弹出的符号放入post,直到栈顶元素的优先级别小于当前运算符,或栈已空,或者栈顶元素已经是‘(’,停止弹栈,将当前运算符压栈。转化时判断表达式是否有误。共判断了5种非法情况:一个数中有两个小数点、数字后直接跟括号、左右括号数量不等、有连续两个运算符之间没有数字、输入了非数字非运算符的东西。如果第一个数是负数,则用0减去第一个数。转化好了以后进行计算。遍历post,如果遍历到数字,则将数字转化为double类型并存到数字栈shu中,如果是运算符,则将栈顶两个数弹栈,将这两个数的运算结果入栈。最后输出保留两位小数的运算结果。
源代码
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include"math.h"
#define N 50
typedef struct mystack{
int a[N];
int top;
}ST;//栈
int isempty(ST *T){
//判断栈是否为空
if(T->top<0)
return 1;
else
return 0;
}
int isfull(ST *T){
//判断栈是否为满
if(T->top==N-1)
return 1;
else
return 0;
}
int gettop(ST *T){
//得到栈顶元素
return T->a[T->top];
}
int pop(ST *T){
//弹栈
int x;
if(T->top<0){
printf("can not pop\n");
exit(0);
}
else{
x=T->a[T->top];
(T->top)--;
return x;
}
}
void push(ST *T,int x){
//入栈
if(T->top==N-1){
printf("can not push\n");
exit(0);
}
else{
(T->top)++;
T->a[T->top]=x;
}
}
void transfer(char *in,char *post){
//将中缀表达式转化为后缀表达式
ST T;//栈
int i,j