栈的应用--中缀与后缀表达式

17 篇文章 0 订阅
14 篇文章 0 订阅


算法流程 :中缀转后缀
1.顺序扫面整个中缀表达式
2.中缀表达式的元素分为两种类型,操作数和操作符。如果当前元素为操作数,则直接将该元素存储后缀表达式当中
3.如果当前操作的事操作符,那么要分几种情况
    3.1 如果当前的运算符是(“(”)则直接将其入栈。
    3.2如果是(“)”),则将栈中的操作符出栈,直到遇到“)” (这里需要强调的是括号是不需要进入后缀表达式的)
    3.3 如果是其他的运算符(+、-、*、/)如果这个运算度的优先级高于栈顶元素的优先级,那么将这个元素入栈,
    如果小于或者等于栈顶运算符的优先级,则将栈顶元素依次弹出,直到该操作符的优先级大于栈顶操作符的优先级
    或者为“(”为止,保持当前栈顶的操作符不变,并将当前操作符入栈
4 扫描整个中缀表达式后,检测操作符栈,依次弹出其中的操作符,并按序存入到后缀表达式中。

#include<iostream>
#include<vector>
#include<string.h>
#include<algorithm>
#include<map>
#include<stack>
#define MAX_Size 100;
using namespace std;
//中缀转后缀 :
//(1)初始化每个运算符的优先级
void init_op(map<string,int> &ops)
{
    ops.clear();
    ops["+"] =100;
    ops["-"] =100;
    ops["*"] = 200;
    ops["/"] = 200;
    ops["("] = 10000;
    ops[")"] = 0;
}
//(2)查看表达式中的元素是不是操作符
bool is_opertor(const string &s, map<string,int> ops)
{
    ops.clear();
    map<string,int> ::const_iterator cit = ops.find(s);
    if(cit != ops.end())
        return  true;
    return false;
}
//核心操作 中缀转后缀
void is2operator(vector<string> &info, vector<string> & postf,map<string,int> &ops)
{
stack<string> s;
postf.clear();//存后缀表达式

for(vector<string> ::size_type i= 0; i< info.size();++i)
{
 if(!is_opertor(info[i],ops))
 {
     postf.push_back(info[i]);
 }
 else
 {
     if(info[i] =="(")
        s.push(info[i]);
     else if(info[i]==")")
     {
        while(!s.empty()&&s.top()!="(")
        {
        //s.push(info[i]);
        postf.push_back(s.top());
        s.pop();
        }
        if(!s.empty()&&s.top()== "(")
        s.pop();//出栈“(”
     }
     else
     {
         if(s.empty())
          s.push(info[i]);
          else
          {

                while(!s.empty() && ops[info[i]]<=ops[s.top()]&& s.top()!="(")
                {
                    postf.push_back(s.top());
                    s.pop();
                }
                s.push(info[i]);
          }
     }
 }
 
}
while(!s.empty())
{
    postf.push_back(s.top());
    s.pop();
}

}
//第二部分 后缀表达式的计算

 int main()
{
/*
测试程序
*/
vector<string> v;
v.push_back("(");
v.push_back("a");
v.push_back("+");
v.push_back("b");
v.push_back("+");
v.push_back("c");
v.push_back("*");
v.push_back("d");
v.push_back(")");
v.push_back("/");
v.push_back("e");
vector<string> vv;
map<string,int> ms;
init_op(ms);
is2operator(v,vv,ms);
for(int i =0;i<vv.size();i++)
{
    cout<< vv[i];
}
   
}

//为什么需要这样转换呢,这其实与计算机内部的运算逻辑有关,也就是这样的结构便于计算机的计算
这个就是内在结构
算法流程:后缀的计算
后缀表达式在计算机中的处理流程大概如下所示:
(1)初始化一个空栈
(2)依次将后缀表达式中的数字入栈,直到遇到操作符,
(3)从栈中取出两个操作数,分别作为右操作数和左操作数 进行运算 将运算结果存入栈中
(4)依次执行(2)(3)操作 直到栈变为空

oid intertopre( vector<string> info,vector<string> & postf,map<string,int> &ops  )
{
	postf.clear();
	stack<string> s1; // 操作符栈
	for (int i = info.size() - 1; i >= 0; --i) // 从右到左扫描
	{
		if (!is_opertor(info[i], ops)) // 如果是操作数
		{
			postf.push_back(info[i]);
		}
		else // 如果是操作符
		{
			if (info[i] == ")") // 如果是右括号,则直接入栈
			{
				s1.push(info[i]);
			}
			else if (info[i] == "(") // 如果是左括号
			{
				// 依次弹出栈中的操作符,直至遇到右括号
				while (!s1.empty())
				{
					if (s1.top() == ")")
					{
						s1.pop();
						break;
					}
					else
					{
						postf.push_back(s1.top());
						s1.pop();
					}
				}
			}
			else // 如果是其他操作符
			{
				while (!s1.empty() && s1.top() != ")" && ops[s1.top()] > ops[info[i]]) // 栈顶操作符优先级大于当前操作符优先级
				{
					postf.push_back(s1.top());
					s1.pop();
				}
				// 将当前操作符入栈
				s1.push(info[i]);
			}
		}
	}

	// 检测操作符栈是否为空
	while (!s1.empty())
	{
		postf.push_back(s1.top());
		s1.pop();
	}
	// 将prefix翻转
	reverse(info.begin(), info.end());
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值