中缀表达式转后缀表达式 & 后缀表达式求值 & 后缀表达式建树

中缀表达式求值 = 中缀转后缀 + 后缀表示式求值

1. 中缀表达式转后缀表达式

12+8-25/3-6*(5+3)

12 8 + 25 3 / - 6 5 3 + * -

中缀表达式字符串从左至右,

  1. 若遇到运算数,则直接将数字输出

  2. 若遇到运算符 ±*/ ,则与栈顶元素比较,若是该运算符优先级高于栈顶元素优先级,则入栈;若是该运算符低于或等于栈顶元素优先级,则将栈顶元素出栈并输出,继续将该运算符与栈顶元素比较,直到该运算符优先级高于栈顶元素优先级,将其入栈。

  3. 若遇到左括号,则入栈,若遇到右括号,则将左括号之前的所有元素出栈。

  4. 读到字符串尾,将所有堆栈元素依次弹出。

    注:

    同优先级左边的运算符优先级更高;

    栈顶元素为空时,空元素优先级最低;

    左括号入栈之前优先级最高,入栈之后优先级最低。

    示例图取自浙大数据结构mooc

//本函数C++实现,支持的运算符仅为 + - * /  ()  
string midToPost(string mid) {
	stack<char> stk;
	string post;
	for (int i = 0; i < mid.length(); i++) {
		//cout << post << endl;
		if (mid[i] >= 'a'&&mid[i] <= 'z') {
			post += mid[i];
		}
		else if (mid[i] == '+' || mid[i] == '-') {
			if (stk.empty() || stk.top() == '(') {
				stk.push(mid[i]);
			}
			else {
				post += stk.top();
				stk.pop();
				while (!stk.empty() && stk.top() != '(') {
					post += stk.top();
					stk.pop();
				}
				stk.push(mid[i]);
			}
		}
		else if (mid[i] == '*' || mid[i] == '/') {
			if (stk.top() == '+' || stk.top() == '-' || stk.empty() || stk.top() == '(') {
				stk.push(mid[i]);
			}
			else {
				post += stk.top();
				stk.pop();
				while (!stk.empty() && stk.top() != '(') {
					post += stk.top();
					stk.pop();
				}
				stk.push(mid[i]);
			}
		}
		else if (mid[i] == '(') {
			stk.push(mid[i]);
		}
		else if (mid[i] == ')') {
			while (stk.top() != '(') {
				post += stk.top();
				stk.pop();
			}
			stk.pop();
		}
		else {
			cout << "表达式格式有误或遇到不明字符!" << endl;
		}
	}
	while (!stk.empty()) {
		post += stk.top();
		stk.pop();
	}
	return post;
}

2. 后缀表达式求值

后缀字符串从左至右扫描:

  1. 若遇到运算数,则入栈
  2. 若遇到运算符,则取栈顶两个元素进行运算后入栈
  3. 直到后缀表达式扫描结束,栈里只剩下一个元素,即为表达式的值
int getValue(string post) {
	stack<int> stk;
	for (int i = 0; i < post.length(); i++) {
		if (post[i] >= 'a' && post[i] <= 'z') {
			stk.push(post[i]);
		}
		else {
			int tmp = stk.top();
			stk.pop();
			switch(post[i]){
				case '+':{
					tmp += stk.top();
					break;
				}
				case '-':{
					tmp -= stk.top();
					break;
				}
				case '*':{
					tmp *= stk.top();
					break;
				}
				case '/':{
					tmp /= stk.top();
					break;
				}
			}
			stk.pop();
			stk.push(tmp);
		}
	}
	return stk.top();
}

3.后缀表达式建树

后缀字符串从左至右扫描:

  1. 若遇到运算数,则建立一个节点,值为该运算数,将节点指针入栈
  2. 若遇到运算符,则建立一个节点,值为该运算符,将栈顶两个元素出栈,分别为当前节点的左右子树,将当前节点指针入栈
  3. 直到后缀表达式扫描结束,栈里只剩下一个元素,即为表达式树的根节点
struct node {
	char data;
	node* left;
	node* right;
};

node* buildTree(string post) {
	stack<node*> stk;
	for (int i = 0; i < post.length(); i++) {
		node* tmp = new node;
		tmp->left = NULL;
		tmp->right = NULL;
		if (post[i] >= 'a' && post[i] <= 'z') {
			tmp->data = post[i];
			stk.push(tmp);
		}
		else {
			tmp->data = post[i];
			tmp->right = stk.top();
			stk.pop();
			tmp->left = stk.top();
			stk.pop();
			stk.push(tmp);
		}
	}
	return stk.top();
}

  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值