3-2 求前缀表达式的值
算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。前缀表达式指二元运算符位于两个运算数之前,例如2+3*(7-4)+8/4的前缀表达式是:+ + 2 * 3 - 7 4 / 8 4。请设计程序计算前缀表达式的结果值。
输入格式:
输入在一行内给出不超过30个字符的前缀表达式,只包含+、-、*、\以及运算数,不同对象(运算数、运算符号)之间以空格分隔。
输出格式:
输出前缀表达式的运算结果,保留小数点后1位,或错误信息ERROR。
输入样例:
+ + 2 * 3 - 7 4 / 8 4
输出样例:
13.0
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct shuju {
double data[30];
int top;
};
void zhan_DZ(struct shuju *Data, double num) //压栈
{
Data->top ++;
Data->data[Data->top] = num;
}
double zhan_CZ(struct shuju *Data) //出栈
{
double num;
num = Data->data[Data->top];
Data->top --;
return num;
}
double Math(double v1, double v2, char c) //运算
{
double sum;
switch(c) {
case '+':
sum = v1 + v2;
break;
case '-':
sum = v1 - v2;
break;
case '*':
sum = v1 * v2;
break;
case '/':
sum = v1 / v2;
break;
}
return sum;
}
int main(void)
{
struct shuju Data;
Data.top = -1; //赋空
int i, flag = 1; //flag用于判断是否正常退出,flag==1正常,flag==0错误
double num, v1, v2;
char s[30]; //储存用户输入的数据
char symbol;
gets(s);
i = strlen(s);
i --;
while(i >= 0){ //后往前读
if(s[i] == ' ') { //遇到空格,跳过
i --;
continue;
}
//如果是0~9的数字,或者是-号且后面不是空格(说明是符号,而不是减号)
if(s[i] >= '0' && s[i] <= '9') {
/*
*如果是0~9或者是负号或者是加号或者是小数点,则一直循环,并且i往前移动,
*其实就是为了找到一个数字的开头地址
*/
for( ; (s[i] >= '0' && s[i] <= '9') ||
(s[i] == '-' && s[i+1] != ' ') ||
(s[i] == '+' && s[i+1] != ' ') ||
s[i] == '.'; i --) ; //注意有分号,空语句
if(i < 0) { //第一个是数字或加号、负号,i会 = -1
i = 0;
}
num = atof(s+i);
zhan_DZ(&Data, num);
}
else {
symbol = s[i];
v1 = zhan_CZ(&Data);
v2 = zhan_CZ(&Data);
if(s[i] == '/' && v2 == 0){
flag = 0;//非正常退出,标记
}
else {
zhan_DZ(&Data, Math(v1, v2, s[i])); //将计算结果压栈
}
}
i --;
}
/*判断是否正常退出*/
if(flag == 1) {
printf("%.1lf\n", Data.data[0]);
}
else {
printf("ERROR\n");
}
return 0;
}