题目描述:
人们的日常习惯是把算术表达式写成中缀式,但对于机器来说更“习惯于”后缀式,关于算术表达式的中缀式和后缀式的论述一般的数据结构书都有相关内容可供参看,这里不再赘述,现在你的任务是将中缀式变为后缀式。
输入描述:
第一行输入一个整数n,共有n组测试数据(n<10)。 每组测试数据只有一行,是一个长度不超过1000的字符串,表示这个运算式的中缀式,每个运算式都是以“=”结束。这个表达式里只包含+-*/与小括号这几种符号。其中小括号可以嵌套使用。数据保证输入的操作数中不会出现负数。 数据保证除数不会为0
输出描述:
每组都输出该组中缀式相应的后缀式,要求相邻的操作数操作符用空格隔开。
样例输入:
复制
2 1.000+2/4= ((1+2)*5+1)/4=
样例输出:
1.000 2 4 / + = 1 2 + 5 * 1 + 4 / =
根据符号优先级计算,相同优先级按顺序先后计算。
以下摘自百度百科:
A、 为“(”
运算符:
压入临时堆栈中
B、 为“)”运算符:
不断地弹出临时堆栈顶部运算符直到顶部的运算符是“(”为止,从栈中删除'('。并把弹出的运算符都添加到后缀表达式中。
C、 为其他运算符,有以下步骤进行:
比较该运算符与临时栈栈顶指针的运算符的优先级,如果临时栈栈顶指针的优先级大于等于该运算符的优先级,弹出并添加到后缀表达式中,反复执行前面的比较工作,直到遇到一个栈顶指针的优先级低于该运算符的优先级,停止弹出添加并把该运算符压入栈中。
此时的比较过程如果出现栈顶的
指针为‘(’,则停止循环并把该运算符压入栈中,注意:‘(’不要弹出来。
遍历完中缀表达式之后,检查临时栈,如果还有
运算符,则全部弹出,并添加到后缀表达式中。
#include<string.h>
#include<algorithm>
#include<iostream>
#include<stack>
#include<stdio.h>
using namespace std;
stack <char>q;
int f[100];
string str;
int main()
{
int n;
cin>>n;
f['+']=f['-']=1;
f['*']=f['/']=2;
while(n--)
{
cin>>str;
int len=str.size();
for(int i=0; i<len&&str[i]!='=';i++)
{
if((str[i]<='9'&&str[i]>='0')||str[i]=='.')
{
while((str[i]<='9'&&str[i]>='0')||str[i]=='.')
{
cout<<str[i];
i++;
}
cout<<" ";
}
if(str[i]=='(')
{
q.push(str[i]);
}
else if(str[i]=='+'||str[i]=='-'||str[i]=='*'||str[i]=='/')
{
while(!q.empty()&&f[q.top()]>=f[str[i]]&&q.top()!='(')
{
cout<<q.top()<<" ";
q.pop();
}
q.push(str[i]);
}
else if(str[i]==')')
{
while(q.top()!='(')
{
cout<<q.top()<<" ";
q.pop();
}
q.pop();
}
}
while(!q.empty())
{
cout<<q.top()<<" ";
q.pop();
}
cout<<'='<<" "<<endl;
}
}