后缀表达式的求值2021/5/3

 终于结局了,是(*str)++和(*str++)形式整错了

要点:atof函数把字符串数组元素转换成浮点数

isdigit函数只能判断字符型是否是数字

#include <stdio.h>
#include <stdlib.h>			//atof函数
#include <ctype.h>			//字符串有关处理的函数 
#include <stdbool.h>		//bool类型 
#define MAXOP 100 			//数组最大值 
#define INFINITY 1e9		//正无穷 
typedef double ElementType;
typedef enum {num, opr, end} Type;
typedef int Position;
typedef struct SNode *PtrToNode;
typedef PtrToNode Stack;		//堆栈 
struct SNode {
	ElementType *Data;
	Position top;
	int MaxSize;
};

Stack CreateStack(int MaxSize) {		//堆栈的创建 
	Stack S = (Stack)malloc(sizeof(struct SNode));
	S->Data = (ElementType *)malloc(sizeof(ElementType) * MaxSize);
	S->top=-1; 
	S->MaxSize = MaxSize;
	return S;
}

bool IsFull(Stack S) {					//是否满 
	return (S->top == S->MaxSize - 1);
}

bool IsEmpty(Stack S) {					//是否空 
	return (S->top == -1);
}

bool Push(Stack S, ElementType x) {		//入栈 
	if (IsFull(S)) {
		printf("堆栈满\n");
		return false;
	} else {
		S->Data[++(S->top)] = x;
		return true;
	}
}

ElementType Pop(Stack S) {				//出栈 
	if (IsEmpty(S)) {
		printf("堆栈空");
		return false;
	} else {
		return (S->Data[(S->top)--]);
	}
}

Type GetOp(char *Expr, int *start, char *str) {
	int i = 0;
	while ((str[0] = Expr[(*start)++]) == ' ');		//把Expr中第一个不空的元素给str[0] 
	while (str[i] != ' ' && str[i] != '\0')			//把Expr中下一个部位空的值给str 
		str[++i] = Expr[(*start)++];
	if (str[i] == '\0')			//读完了 
		(*start)--;				
	str[i] = '\0';			//当没有读完,而是把空格赋值给了str[i]时,需要给它赋值‘\0’,在atof时要用到 
	if (i == 0)
		return end;
	else if (isdigit(str[0]) || isdigit(str[1]))		//表示str存的一个数字, isdigit(str[1])?? 
		return num;
	else				//存的是运算符 
		return opr;
}

ElementType PostfixExp (char *Expr) {
	Stack S;
	Type T;
	ElementType Op1, Op2;
	char str[MAXOP];				//用来存储每次读入的对象 
	int start = 0;
	S = CreateStack(MAXOP);			//创建堆栈 
	Op1 = Op2 = 0;
	while ((T = GetOp(Expr, &start, str)) != end) {		//没读到结束 
		if (T == num) {
			Push(S, atof(str));				//数字就入栈 
		} else {
			if (!IsEmpty(S))		//如果此时堆栈不空,就把栈顶元素给Op2,下一个给Op1来进行运算 
				Op2 = Pop(S);
			else
				Op2 = INFINITY;		//栈顶是空的说明表达式出错了,就给op2赋值临界点,就出去了 
			if (!IsEmpty(S))
				Op1 = Pop(S);
			else
				Op2 = INFINITY;
			switch (str[0]) {
				case '+':
					Push(S, Op1 + Op2);
					break;
				case '-':
					Push(S, Op1 - Op2);
					break;
				case '*':
					Push(S, Op1 * Op2);
					break;
				case '/':
					if (Op2!=0.0) {
						Push(S, Op1 / Op2);
					} else {
						printf("错误:分母为零\n");
						Op2 = INFINITY;
					}
					break;
				default:
					printf("错误:未知运算符%s\n", str);
					Op2 = INFINITY;
					break;
			}
			if (Op2 >= INFINITY)			//检查到错误情况,出去 
				break;
		}
	}
	if (Op2 < INFINITY) {					
		if (!IsEmpty(S))					//没有错误情况并且堆栈里不空,那么哪个元素就是最终值 
			Op2 = Pop(S);
		else
			Op2 = INFINITY;

	}
	free(S);
	return Op2;
}

int main() {
	char Expr[MAXOP];
	ElementType f;
	
	gets(Expr);
	
	f = PostfixExp(Expr);
	if (f < INFINITY)
		printf("%.4f\n", f);
	else
		printf("表达式错误\n");
	return 0;
}

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值