算法流程 :中缀转后缀
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());
}