3.19 编写一个程序计算后缀表达式的值
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
/*
* 1.用链表实现栈
* 2.后缀表达式中含有小数,'+' '*'运算符和空格
* 3.输入的后缀表达式必须以'#'结尾,不同的数之间必须用空格隔开
* 4.小数点后最多两位,小数点前最多3位数
* 5.atof()函数:将字符串转换为double(双精度浮点数)
*
*/
typedef struct Node { //栈中的一个节点
double data;
struct Node* pNext;
}Node, *PtrNode;
typedef struct Stack {
PtrNode pTop; //指向栈顶部元素
}Stack, *PtrStack;
PtrStack initStack(void); //初始化栈
PtrNode newNode(double val);//创建新的节点
bool isEmpty(PtrStack pStack);//判断栈是否为空
bool isDigit(char ch); //判断是否为数字字符
void Push(PtrStack pStack, double val);//入栈
double Pop(PtrStack pStack); //出栈,返回出栈的值
void showStack(PtrStack pStack); //从顶部依次输出栈中的元素
void caculate(PtrStack pStack, char ch);//碰到运算符,就进行计算
void pushDigit(PtrStack pStack, char ch);//碰到数字,将字符串转化为double,压入栈中
int main(void) {
PtrStack pStack = initStack();
char ch = getchar();
while (ch != '#') {
if (ch == '+' || ch == '*')//碰到运算符
caculate(pStack, ch);//进行计算
else if (isDigit(ch))//碰到数字
pushDigit(pStack, ch);//将字符串转化为double,压入栈中
ch = getchar();
}
showStack(pStack);
return 0;
}
PtrStack initStack(void) {//初始化栈
PtrNode pHead = (PtrNode)malloc(sizeof(Node));//链表的头节点
if (pHead == NULL) {
printf("1.分配内存失败!\n");
exit(-1);
}
else
pHead->pNext = NULL;
PtrStack pStack = (PtrStack)malloc(sizeof(Stack));//初始栈,pTop指向pHead
if (pStack == NULL) {
printf("2.分配内存失败!\n");
exit(-1);
}
else
pStack->pTop = pHead;
return pStack;
}
PtrNode newNode(double val) {
PtrNode newNode = (PtrNode)malloc(sizeof(Node));
if (newNode == NULL) {
printf("分配内存失败!\n");
exit(-1);
}
else {
newNode->data = val;
newNode->pNext = NULL;
}
return newNode;
}
bool isEmpty(PtrStack pStack) {
return pStack->pTop->pNext == NULL;
}
bool isDigit(char ch) {
return ch - '0' >= 0 && ch - '0' <= 9;
}
void Push(PtrStack pStack, double val) {
PtrNode pNew = newNode(val);
pNew->pNext = pStack->pTop;
pStack->pTop = pNew;
}
double Pop(PtrStack pStack) {
if (isEmpty(pStack)) {
printf("栈为空!\n");
exit(-1);
}
else {
PtrNode pTemp = pStack->pTop;
pStack->pTop = pStack->pTop->pNext;
double temp = pTemp->data;
free(pTemp);
return temp;
}
}
void showStack(PtrStack pStack) {
if (isEmpty(pStack)) {
printf("栈为空!\n");
exit(-1);
}
else {
PtrNode p = pStack->pTop;
while (p->pNext != NULL) {
printf("%.2f\t", p->data);
p = p->pNext;
}
printf("\n");
}
}
void caculate(PtrStack pStack, char ch) {
double temp1 = Pop(pStack);
double temp2 = Pop(pStack);
switch (ch) {
case '+':
Push(pStack, temp1 + temp2);
break;
case '*':
Push(pStack, temp1 * temp2);
break;
}
}
void pushDigit(PtrStack pStack, char ch) {
char temp[10];//用来存储数字字符,再用atof()函数转换为double型
int i;
i = 0;
temp[i] = ch;
/*如果下一个仍是数字字符或小数点则继续存入
* while循环结束时,如果ch=' ',则不管
* 如果ch是运算符,则执行caculate函数
*/
while (isDigit(ch = getchar()) || ch == '.')
temp[++i] = ch;
temp[++i] = '\0';
Push(pStack, atof(temp));
if (ch == '+' || ch == '*')//碰到运算符
caculate(pStack, ch);
}