《数据结构与算法分析:C语言描述》习题3.19

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);
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值