题意:
给定表达式,输出前缀,中缀,后缀表达式
思路:
可以利用表达式树的前序,中序,后序遍历,也可以利用栈进行操作。
栈的思路解析:
前缀:
我们按照运算符优先级来操作,优先级小的就直接输出,优先级大的碰到更大的或者
0.需要两个栈,一个是输出栈,一个是暂存栈,我们对得到的表达式字符串进行逆序枚举
1.如果当前字符是操作符,直接入输出栈
2.若当前运算符的优先级低于暂存栈顶运算符,就将栈顶运算符入输出栈并出暂存栈,直到当前运算符优先级等于或大于暂存栈顶运算符,我们让它入暂存栈
3.当然,暂存栈顶没有东西的时候,就直接入暂存栈就好了
4.括号,就相当于分隔符,读到左括号的时候,将右括号上方所有运算符入输出栈并出暂存栈
5.枚举结束后,先将暂存栈所有元素入输出栈,再依次输出输出栈
中缀:
跳过输出()即可
后缀:
与前缀同理,不过它只需要一个栈。
只要是操作数就输出,只要是运算符,并且比栈顶运算符优先级大就入栈。
如果优先级小,我们就让栈里的都出去,再让它进去,因为括号是个分隔符,所以到括号停下即可。
当然,栈里没有东西的时候,操作符就直接入栈。
三个主要的函数代码如下:
void pre(char str[])
{
for(int i=strlen(str)-2;i>=0;i--)
{
char x=str[i];
if(x>='a'&&x<='z')
{
b.push(x);
}
else
{
if(x==')'||n.empty())
{
n.push(x);
}
else if(x=='(')
{
while(n.top()!=')')
{
b.push(n.top());
n.pop();
}
n.pop();
}
else if(x=='*'||x=='/')
{
n.push(x);
}
else if(x=='+'||x=='-')
{
if(n.top()==x)
{
n.push(x);
}
else
{
while(!n.empty()&&n.top()!=')')
{
if(n.top()=='*'||n.top()=='/')
{
b.push(n.top());
n.pop();
}
else
{
break;
}
}
n.push(x);
}
}
}
}
while(!n.empty())
{
b.push(n.top());
n.pop();
}
while(!b.empty())
{
cout<<b.top();
b.pop();
}
cout<<endl;
}
void in(char str[])
{
for(int i=0;str[i]!='#';i++)
{
if(str[i]!='('&&str[i]!=')')
cout << str[i];
}
cout << endl;
}
void post(char str[])
{
for(int i=0;i!='#';i++)
{
char x=str[i];
if(x>='a'&&x<='z')
cout <<x;
else
{
if(x=='('||f.empty())
{
f.push(x);
}
else if(x == ')')
{
while(f.top()!='(')
{
cout<<f.top();
f.pop();
}
f.pop();
}
else if(x=='+'||x=='-')
{
while(!f.empty()&&f.top()!='(')
{
cout<<f.top();
f.pop();
}
f.push(x);
}
else if(x=='*'||x=='/')
{
while(!f.empty()&&f.top()!='(')
{
if(f.top()=='*'||f.top()=='/')
{
cout << f.top();
f.pop();
}
else break;
}
f.push(x);
}
}
}
while(!f.empty())
{
cout << f.top();
f.pop();
}
cout <<endl;
}