中缀表达式转为后缀表达式的堆栈实现

中缀表达式转为后缀表达式的堆栈实现

中缀表达式
日常用到的表达式。
1+2*3-4

1+2-3*4/5

后缀表达式
把运算符放在两运算数后。每次遇到运算符时就将前两个运算数进行运算。

1 2 3 * + 4 -

1 2 + 3 4 * 5 / -
.
.
.
.
在这里插入图片描述
一个人学习cpp太艰难了
希望有大佬指点或者相互讨论学习

/*
	Name: 中缀表达式转为后缀表达式的堆栈实现 
	Copyright: 
	Author: 小张同学.AC 
	Date: 28/09/21 20:01
	Description: 
	完成了只含四则运算的表达式,还没考虑有括号的情况。
	用到了引用,得在.cpp中运行 。
	堆栈由链表实现。
	我用的编译器是DveC++ 5.4.0。 
*/
#include <stdio.h>
#include <stdlib.h>

typedef char ElementType;

typedef struct SNode{
	ElementType Data;
	struct SNode *Next;
}Stack;

char Number[] = {'0','1','2','3','4','5','6','7','8','9',};
char Space = ' ';

/* 以下用链表实现堆栈的相关函数 */
int IsEmpty(Stack* S){//判断堆栈是否空 
	return (S->Next == NULL);
} 
Stack* CreateStack(){
	Stack* S;
	S = (Stack*)malloc(sizeof(Stack));
	S->Next = NULL;
	return S;
}
void Push(Stack* S, ElementType item){
	Stack* tmpCell;//以malloc函数申请空间,不需要对堆栈满进行判断 
	tmpCell = (Stack*)malloc(sizeof(Stack));
	tmpCell->Data = item; 
	tmpCell->Next = S->Next;
	S->Next = tmpCell;
}
ElementType Pop(Stack* S){
	Stack* FirstCell;
	ElementType TopElem; 
	if(IsEmpty(S)){
		printf("堆栈空!");
		return NULL; 
	}else{
		FirstCell = S->Next;
		S->Next = FirstCell->Next;
		TopElem = FirstCell->Data;
		free(FirstCell);
		return TopElem; 
	}
}
/* 链表实现堆栈结束 */
 
//读入中缀表达式
int Scan(ElementType &item){
	int Flag = 0;
	scanf("%c", &item);
	return item == '\n' ? 0 : 1;//若读到回车说明输入结束 
}
void Print(ElementType &item){
	printf("%c", item);
}
int IsNumber(ElementType &item){
	int Flag = 0;
	int i;
	for(i=0; i<sizeof(Number)/sizeof(char); i++){//循环判断是不是数字
		if(item == Number[i]){
			Flag = 1;
			break;
		}
	}
	return Flag;
}
/* 转为后缀表达式关键函数 (⊙o⊙)…就是处理优先级的问题 */
void PK(Stack* S, ElementType thisItem){
	ElementType preItem;
	if(IsEmpty(S)){//如果是堆栈是空,则直接进栈 
		Push(S, thisItem);
	}else{
		while(!IsEmpty(S)){
			/* 弹出前一个运算符 */
			preItem = Pop(S);
			/* 在这里对前一个运算符和当前运算符做一些优先级处理 
			   对“+”“-”用1标志;对“*”“/”用2标志 */
			int flagPre, flagThis;
			flagThis = (thisItem == '+' || thisItem == '-') ? 1 : 2;
			flagPre = (preItem == '*' || preItem == '/') ? 2 : 1;
			/* 循环弹出堆栈内的运算符进行比较 */
			if(flagPre >= flagThis){
			    /* 若前一个运算符优先级高于当前运算符优先级 或者 级别相同,则弹出前一个运算符 */
				Print(preItem);
				Print(Space);
			}else{
			    /* 若前一个运算符优先级低于当前运算符优先级,则弹入堆栈中等待并退出比较 */
				Push(S, preItem);
				//Tag 标记行 
				break;
			}
		}
		/* while循环若是因为堆栈空退出,则不会将当前运算符弹入堆栈中等待 
		   所以 Push(S, thisItem)不能放在Tag标记行中 */ 
		Push(S, thisItem);
	}
}

int main(){
	ElementType item;
	Stack* S;
	S = CreateStack();
	
	while(Scan(item)){
		/* 区分读入的是运算数还是运算符 */
		if(IsNumber(item)){
			Print(item);//是运算数则直接输出 
		}else{
			Print(Space);
			PK(S, item);//是运算符则进行优先级比较 
		}
	}
	/* 输出堆栈内的剩余运算符 */
	while(!IsEmpty(S)){
		Print(Space);
		item = Pop(S);
		Print(item);
	}
	puts("");
	
	return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值