一、算术表达式转为后缀式
主要思路:从左到右扫描算术表达式,遇到的操作数直接存放到后缀表达式中,遇到的运算符以及左括号都暂时保存到运算符栈且先执行的运算符先出栈。
前提说明:exp:中缀表达式;postexp:后缀表达式;
方法描述:在扫描exp遇到一个运算符op时,
1、若栈为空,直接进栈
2、若不为空,当op的优先级高于栈顶运算符的优先级时才直接将op进栈,否则依次出栈并存入postexp,直到栈顶运算符的优先级小于op的优先级为止,然后再将op进栈。
3、若op为 ‘(’ ,直接进栈。
4、若op为 ‘)’ ,出栈运算符并存入postexp,直到栈顶为 ‘(’ ,再将 ‘(’ 出栈。
5、若op为其他运算符,而栈顶为 ‘(’ ,直接进栈。
//中缀表达式假如只考虑+、-、*、/、(、)
string trans(string exp)
{
string postexp="";
stack<char> stack;
int i=0;
while(i<exp.size())
{
switch(exp[i])
{
case '(':
stack.push('(');
i++;
break;
case ')':
while(stack.top()!='(')
{
postexp+=stack.top();
stack.pop();
}
stack.pop();
i++;
break;
case '+':
case '-':
while(!stack.empty())
{
if(stack.top()=='(')
{
stack.push(exp[i]);
break;
}
else
{
//对于当前情况,栈中没有运算符小于+、-;因此只有在栈中遇到 '(' 才停止出栈。
postexp+=stack.top();
stack.pop();
}
}
if(stack.empty())
stack.push(exp[i]);
i++;
break;
case '*':
case '/':
while(!stack.empty())
{
if(stack.top()=='(')
{
stack.push(exp[i]);
break;
}
//遇到*、/出栈,碰到 '(' 停止;
else if(stack.top()=='*'||stack.top()=='/')
{
postexp+=stack.top();
stack.pop();
}
else
break;
}
if(stack.top()!=exp[i])
stack.push(exp[i]);
i++;
break;
default:
while(exp[i]>='0'&&exp[i]<='9'||exp[i]>='a'&&exp[i]<='z'||exp[i]>='A'&&exp[i]<='Z'||exp[i]=='_')
{
postexp+=exp[i++];
}
postexp+='#';
}
}
while(!stack.empty())
{
postexp+=stack.top();
stack.pop();
}
cout<<postexp<<endl;
return postexp;
}
二、后缀运算表达式转中间代码
方法描述:从左到右扫描后缀式postexp,
1、若读取的是一个操作数,将它进操作数栈opnd。
2、若读取的是一个运算符op,从操作数栈中连续出栈两个操作数,假如说是a,b,定义一个变量T(存储计算结果的变量),将它变成四元式(op,a,b,T)并将T进操作数栈
vector<string> arithMiddle(string postexp,int &n)
{
vector<char> op={'+','-','*','/'};
vector<string> middle;
stack<string> opnd;
string s="";
for(int i=0;i<postexp.size();i++)
{
if(find(op.begin(),op.end(),postexp[i])==op.end())
{
if(postexp[i]=='#')
{
opnd.push(s);
s="";
}
else
s+=postexp[i];
}
else
{
string a=opnd.top();
opnd.pop();
string b=opnd.top();
opnd.pop();
string T="";
char ch=n+48;
T=T+'T'+ch;
string temp="";
temp=temp+"("+postexp[i]+','+a+','+b+','+T+')';
middle.push_back(temp);
opnd.push(T);
n++;
}
}
for(int i=0;i<middle.size();i++)
cout<<middle[i]<<endl;
return middle;
}