//逆波兰计算器(后缀表达式)
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<ctype.h>//isdigit(c)函数的头文件,用于判断传入的字符c是否为"0-9"的数字字符
#define STACK_INIT_SIZE 20 //栈的初始空间大小
#define STACKINCREMENT 10 //增量,用于追加额外空间
typedef double ElemType;
typedef struct{
ElemType *base;//栈底指针
ElemType *top;//栈顶指针
int stackSize;
}sqStack;
//初始化栈
void 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;
}
//元素入栈
void 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 = e;
s.top++;
}
//元素出栈
void Pop(sqStack &s, ElemType &e){
if( s.top == s.base )
return ;
e = *--s.top;
}
//返回栈的当前容量
int StackLen(sqStack s){
return (s.top-s.base);
}
int main(){
printf("\n假设用逆波兰表达式计算:(1-2)*(4+5)= ? ---- 运算结果应为-9.000000\n");
sqStack s;
InitStack(s);
char c;
double d,e;//支持小数数据的运算,定义成double类型
char str[10];
int i = 0;
printf("\n\n请按逆波兰表达式输入待计算的数据,数据与运算符之间用空格隔开,以‘#’作为结束标志\n");
scanf("%c",&c);
while( c != '#' ){
while( isdigit( c ) || c == '.' ){//数据缓冲区,isdigit()检查参数c是否为阿拉伯数字0到9(字符数字)
str[i++] = c;//如果是数字 字符,将字符存放数组里
if( i >= 10){//规定每个数字的位数小于10
printf("出错:输入的单个数据过大!\n");
return -1;
}
scanf("%c",&c);
if(c == ' '){//如果输入空格,表示一个数据输入结束,将数据元素入栈
d = atof(str);//用于将字符串转换为双精度浮点数(double)
Push(s,d);//遇到数字就入栈,此时入栈的是double类型的数字,不是字符
i = 0;
break ;//跳出while循环
}
}
switch( c ){
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错误:除数不为零!");
return -1;
}
break ;
}
scanf("%c",&c);
}
Pop(s,d);//最后一个元素出栈就是最终的运算结果
printf("\n最终的运算结果为:%f",d);
return 0;
}
|