中缀转后缀表达式 并 计算——代码补全啦——全都是用栈处理的O(∩_∩)O

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

① 两条基本规则: (1)数字无条件输出

                             (2)符号进栈进行相应处理

② 符号处理规则:

(简单点记忆就是,只有最强的才能站在高峰,不够强的,原先的大佬们就要跑路了,携款潜逃偷笑,等大佬都跑光了,才能压制住手下一帮小弟偷笑

    (1)当前符号的优先级 大于 栈顶符号的优先级时, 当前符号压栈

            例:当前符号 * ,栈顶符号 + ,压栈

                

压栈后栈的情况
 
*(栈顶)
+(原栈顶)

    (2)当前符号的优先级 小于等于 栈顶符号的优先级时,先将栈中元素弹出,直到当前栈顶的优先级 小于 待处理的符号的优先级。输入待处理符号为  -  

优先级关系: * == /     >   + == -

原来的栈h后来的栈
*
 
+

-

③ 括号处理

    (1) 左括号  (   无条件压栈;

    (2)右括号      从栈顶开始向下逐个匹配左括号,匹配到了就将这一对括号之间的所有符号依次出栈。

④ 其他的补充:



2. 后缀表达式的计算

上述的处理将后缀表达式存储在一个数组当中。

规则:从左到右地扫描,

    (1)操作数(数字)无条件压栈

    (2)遇到操作码(符号)则从栈里弹出两个数字(先弹出的是第二操作数,后弹出的是第一操作数)

因为除法会产生小数,最好用浮点数的形式存储操作数。

(代码撸出来啦( ̄︶ ̄)↗ ,大家借鉴参考着用吧(●'◡'●))

#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <map>
#include <cstdio>
using namespace std;

map<char, int> prior;
struct NUM
{
	bool flag; // true---num   false---operator
	double number;
	char opera;
};

bool isNum(char c)
{
	if (c >= '0' && c <= '9')
		return true;
	else
		return false;
}

void infix_to_postfix(vector<NUM> &v, string s)
{
	stack<char> op; // for operator
	NUM str_num;
	for (int i = 0; i < s.size();)
	{
		if (isNum(s[i])) {
			str_num.flag = true;
			str_num.number = s[i] - '0';
			i++;
			while (isNum(s[i])) {
				double num_temp = s[i] - '0';
				str_num.number = str_num.number * 10 + num_temp;
				i++;
			}
			v.push_back(str_num);
		}
		else 
		{	// 压栈
			if (op.empty() || (prior[op.top()] < prior[s[i]]) || (s[i] == '('))  
				op.push(s[i]);
			else 
			{
				// 栈中符号都弹完或者出现了比当前符号等级还小的符号,终止弹出操作
				while (!op.empty() && ( (prior[op.top()] >= prior[s[i]]) || (s[i]==')') ) )
				{
					char temp = op.top();
					if (temp == '(') { // 匹配到最近的左括号终止弹出操作
						op.pop();
						break;
					}
					str_num.flag = false;
					str_num.opera = temp;
					v.push_back(str_num);
					op.pop();
				}
				if(s[i]!=')')  //防止再把右括号压入栈
					op.push(s[i]);
			}
			i++;
		}
	}
	// pop all the rest operator in stack
	while (!op.empty())
	{
		char temp = op.top();
		str_num.flag = false;
		str_num.opera = temp;
		v.push_back(str_num);
		op.pop();
	}
}

// 符号计算—— num1 op num2
double cal_op(char op, double num1, double num2)
{
	if (op == '+')
		return num1 + num2;
	else if (op == '-')
		return num1 - num2;
	else if (op == '*')
		return num1*num2;
	else if (op == '/')
		return num1 / num2;
	
	cout << "未识别的计算,请自行完成(●'◡'●)" << endl;
	return 0;
}

// 计算后缀表达式的值——讲真计算一个表达式的值,计算机还是后缀表达式更简单ε=( o`ω′)ノ
double calculate_postfix(vector<NUM> &v)
{
	stack<double> num; // place the number
	for (int i = 0; i < v.size(); ++i)
	{
		if (v[i].flag)
			num.push(v[i].number);
		else
		{
			double num2 = num.top(); num.pop();
			double num1 = num.top(); num.pop();
			num1 = cal_op(v[i].opera, num1, num2);
			num.push(num1); // 结果压栈,有可能还有后续计算
		}
	}
	return num.top();
}

int main(int argc, char const *argv[])
{
	string input;
	vector<NUM> result;
	
	prior['*'] = prior['/'] = 2;
	prior['+'] = prior['-'] = 1;
	cin >> input;

	infix_to_postfix(result, input);
	cout << "postfix" << endl;
	for (int i = 0; i < result.size(); ++i)
	{
	//	cout << result[i].flag << " ";
		if (result[i].flag)
			cout << result[i].number << " ";
		else
			cout << result[i].opera << " ";
	}

	double cal_num = calculate_postfix(result);
	cout << endl << "calculate result: " << cal_num << endl;
	return 0;
}

运行出来的结果是这样的:


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值