栈的应用——求表达式的值(中缀转后缀)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int error;

struct Stack {
	char *data;
	int Top;
	int MaxSize;
};

struct Stack  *CreateStack(int MaxSize) {//创建栈
	struct Stack *S;
	S = (struct Stack *)malloc(sizeof(struct Stack));
	if (S) {
		S->data = (char *)malloc(sizeof(struct Stack) * MaxSize);
		S->Top = -1;
		S->MaxSize = MaxSize;
	}
	return S;
}

void PushStack(struct Stack *&S, char n) { //元素入栈
	S->data[++S->Top] = n;
}

char PopStack(struct Stack *&S) {//元素出栈
	return S->data[S->Top--];
}

int Isdigit(char ch) {//判断是否为数字
	if (ch <= '9' && ch >= '0')
		return 1;
	else
		return 0;
}

char GetTop(struct Stack *&S) {//得到栈顶的元素
	return S->data[S->Top];
}

int IsEmpty(struct Stack *&S) {//判断栈是否为空
	return (S->Top == -1);
}

void Change(char *ch1, char *ch2) { //将中缀表达式转换为后缀表达式,用一个字符型数组存放转换后的后缀表达
	int j = 0;
	struct Stack *S;
	S = CreateStack(50);
	for (int i = 0; ch1[i] != '\0'; i++) {
		if (Isdigit(ch1[i]))
			ch2[j++] = ch1[i++];//数字可以直接存放到数组中
		if (S->Top == -1)
			PushStack(S, ch1[i++]);//栈为空时将运算符入栈
		if (ch1[i] == '(')
			PushStack(S, ch1[i]);//运算符为左括号’(‘时直接入栈
		if (ch1[i] == ')') {
			while (GetTop(S) != '(') {
				ch2[j++] = PopStack(S);
			}
			if (GetTop(S) == '(')
				S->Top--;
		}//运算符为右括号‘)’时,栈中运算符依次出栈,直到栈顶为左括号停止,去掉左括号
		if (ch1[i] == '+' || ch1[i] == '-') {
			while (S->Top != -1 && GetTop(S) != '(') {
				ch2[j++] = PopStack(S);
			}
			PushStack(S, ch1[i]);
		}//运算符为‘+’或‘-’时,栈中元素依次出栈,直到栈为空或者栈顶为左括号‘(’,再将运算符入栈
		if (ch1[i] == '*' || ch1[i] == '/') {
			while (S->Top != -1 && GetTop(S) != '(' && GetTop(S) != '+' && GetTop(S) != '-') {
				ch2[j++] = PopStack(S);
			}
			PushStack(S, ch1[i]);
		}//运算符为‘*’或‘/’时,栈中元素依次出栈,直到栈为空或者栈顶为左括号‘(’,或者栈顶为‘+’,或者栈顶为‘-’,再将运算符入栈
	}
	while (S->Top != -1) {
		if (GetTop(S) != '(')
			ch2[j++] = PopStack(S);
	}//只要栈不为空,若栈顶不为左括号‘(’,将栈顶元素依次出栈
	ch2[j] = '\0';
}

int Calculate(char *ch) {
	int n1, n2;
	struct Stack *S;
	S = CreateStack(50);
	error = 0;
	for (int i = 0; ch[i] != '\0'; i++) {
		switch (ch[i]) {
			case '0':
			case '1':
			case '2':
			case '3':
			case '4':
			case '5':
			case '6':
			case '7':
			case '8':
			case '9':
				PushStack(S, ch[i] - 48);
				break;
			case ' ':
				break;
			case '+':
			case '-':
			case '*':
			case '/':
				if (S->Top != -1)
					n2 = PopStack(S);
				else {
					error = 1;
					return 0;
				}
				if (S->Top != -1)
					n1 = PopStack(S);
				else {
					error = 1;
					return 0;
				}
				switch (ch[i]) {
					case '+':
						PushStack(S, n1 + n2);
						break;
					case '-':
						PushStack(S, n1 - n2);
						break;
					case '*':
						PushStack(S, n1 * n2);
						break;
					case '/':
						PushStack(S, n1 / n2);
						break;
				}
				break;
			default:
				error = 2;
				return 0;
		}
	}
	if (S->Top != 0)
		error = 3;
	return PopStack(S);
}

int main() {
	struct Stack *S;
	S = CreateStack(50);
	char x[50] = {NULL};
	scanf("%s", x);
	char y[50] = {NULL};
	Change(x, y);
	for (int i = 0; y[i] != '\0'; i++) {
		printf("%c ", y[i]);
	}
	printf("\n");
	int r = Calculate(y);
	if (error == 0)
		printf("express result = %d\n", r);
	else
		printf("Error %d. \n", error);
	return 0;
}

运行结果:

(我在Dev-C++上可以运行,但是VS2022上不行,不知道哪里有点问题) 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值