【C++】栈的应用:中缀表达式转后缀(代码实现)

这两天一直在敲这个算法的代码,途中出栈的地方出了一个bug,不会用VS的断点调试,只能慢慢找,最后中途解决了问题。

本文利用了一个数组用作栈,实现中缀表达式(nifix expression)到后缀表达式(postfix expression)的转换。

算法思想如下:

  • 1从左到右扫描中缀表达式
  • 2遇到数字,加入后缀表达式
  • 3遇到运算符:
  •     3.1若是“(”,入栈
  •     3.2若是“)”,依次把栈中的运算符加入后缀表达式,直到出现“(“
  •     3.3若为除括号外的其他运算符:
  •         a 当优先级高于除“(”外的栈顶运算符时,入栈
  •         b 否则,从栈顶开始,依次弹出>=当前处理的运算符优先级的运算符,
  •     直到一个比它优先级低的或遇到了一个左括号为止,并将元素入栈。
  • 4循环第3步直到扫描元素为空
  • 5将栈中剩余元素出栈

具体代码如下,除了主要算法的函数ExpTrans_nifix_to_postfix以外,还写了很多辅助函数,包括出栈pop入栈push给一个操作符返回优先级rank_elem等函数。

#include<iostream>
using namespace std;
#include<string>

#define MAX 100 //表达式最大长度
#define STACK_DEEPTH 20
//本项目:利用栈,将中缀表达式转换成后缀表达式


string ExpTrans_nifix_to_postfix(char s[]);

//用一个数组定义栈
struct stack {
	char arr[STACK_DEEPTH];
	int top =0;//top指向栈顶元素上方一格
};
//入栈函数
bool push(stack &s,char c) {
	if (s.top == STACK_DEEPTH) return false;
	s.arr[s.top++] = c;
	return true;	
}
//出栈函数
char pop(stack &s) {
	if (s.top == 0)return '&';//选一个不常用的字符作为队空时的返回值
	return s.arr[--s.top];
}
//独取栈顶元素
char gettop(stack &s) {
	if(s.top>0)return s.arr[s.top - 1];
	else {
		return'&';
	}
}
//从栈底输出所有元素
void printstack(stack &s) {
	for(int i = 0; i < s.top; i++) {
		cout << s.arr[i] << " " ;
	}
	cout << endl;
}

//给各种元素返回一个优先级
//字母:0  (+ - ) 1  (* /)  2  '( '100  ')'101
int rank_elem(char c) {
	if ((c > 64 && c < 91)||(c>96&&c<123))return 0;
	else if(c=='+'||c=='-') {
		return 1;
	}
	else if (c == '*' || c == '/') {
		return 2;
	}
	else if (c == '(' ) {
		return 100;
	}
	else if (c == ')') {
		return 101;
	}
	else {
		return -1;
	}
}

int main() {

	char s[MAX];
	cout << "***** 中缀表达式 to 后缀表达式 *****\n" << endl;
	cout << "请输入中缀表达式:" << endl;
	cin >> s;
	cout << "后缀表达式为:\n" << ExpTrans_nifix_to_postfix(s) <<endl;

	system("pause");
	return 0;
}

string ExpTrans_nifix_to_postfix(char s[]) {
	string postExp ;//最终要返回的后缀表达式

	stack st;
	for (int i = 0; i < strlen(s); i++) {
		

		switch (rank_elem(s[i])) {
		case 0://字母
			postExp += s[i];
			break;
		case 100:
			push(st, s[i]);
			break;
		case 101: {//如果扫描字符是右括号的情况
			while (true) {
				if (gettop(st) == '(') {
					pop(st);
					break;//直到遇到左括号停止
				}
				postExp += pop(st);

			}
			break;
		}
		default: {
			//优先级高入栈
			if (gettop(st) == '(' || rank_elem(s[i]) > rank_elem(gettop(st))) {
				push(st, s[i]);
			}
			else {
				while (true) {
					if (gettop(st) == '(') {
						//pop(st);
						break;
					}
					if (rank_elem(gettop(st)) < rank_elem(s[i])) {
						break;
					}
					postExp += pop(st);
				}
				push(st, s[i]);
			}
			break;
		}
		}

	}
		//扫描完成,将站内元素清空
		while (st.top != 0) {
		postExp += pop(st);
	}
	return postExp;
}

  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值