PTA 7-20 表达式转换
算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。日常使用的算术表达式是采用中缀表示法,即二元运算符位于两个运算数中间。请设计程序将中缀表达式转换为后缀表达式。
输入格式:
输入在一行中给出不含空格的中缀表达式,可包含+、-、*、\以及左右括号(),表达式不超过20个字符。
输出格式:
在一行中输出转换后的后缀表达式,要求不同对象(运算数、运算符号)之间以空格分隔,但结尾不得有多余空格。
输入样例:
2+3*(7-4)+8/4
输出样例:
2 3 7 4 - * + 8 4 / +
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
测试点如下:
Input | Ouput | Explanation |
---|---|---|
2+3*(7-4)+8/4 | 2 3 7 4 - * + 8 4 / + | sample 6种运算符 |
((2+3)*4-(8+2))/5 | 2 3 + 4 * 8 2 + - 5 / | 嵌套括号 |
1314+25.5*12 | 1314 25.5 12 * + | 运算数超过1位整数且有非整数出现 |
-2*(+3) | -2 3 * | 运算数前有正负号 |
123 | 123 | 只有一个数字 |
解答如下屎山。
#include<stdlib.h>
#include<iostream>
#include<map>
#include<string>
using namespace std;
typedef struct SNode{ //数据类型
char data;
SNode *next;
}SNode, *Stack;
void push(Stack &S, char c) //入栈操作
{
SNode *p;
p = (SNode *)malloc(sizeof(SNode));
p->next = S->next;
S->next = p;
p->data = c;
}
void pop(Stack &S) //出栈操作
{
char c;
SNode *p;
p = S->next;
if(!p)
cout << "ERROR!" << endl;
c = p->data;
S->next = p->next;
free(p);
printf(" %c", c);
}
void delpop(Stack &S) //用于出栈但是不打印的操作
{
SNode *p;
p = S->next;
S->next = p->next;
free(p);
}
void delBracket(Stack &S) //用于删除括号
{
SNode *p;
p = S->next;
while(p->data!='(')
{
pop(S);
p = S->next;
}
delpop(S);
}
bool judgeSet(char c) //判断符号是否在算符集内。
{
if(c=='('||c=='+'||c=='-'||c=='/'||c=='*'||c==')')
return true;
else
return false;
}
void getNumber(string &formula, int &i, int &fir) // 用于打印数字
{
fir==0?fir=1:printf(" ");
for(i;i<formula.size()&&!(judgeSet(formula[i]));i++)
cout << formula[i];
}
int main()
{
string formula;
Stack S;
S = (Stack)malloc(sizeof(SNode));
S->next = NULL;
if(!S)
{
printf("Error allocated!\n");
return -1;
}
map<char, int>mp; //用于设置运算符优先级,map类似python的字典(即键值对)。
mp['/'] = 1;
mp['*'] = 1;
mp['('] = 0;
mp['+'] = 2;
mp['-'] = 2;
cin >> formula;
int i=0; // 用于计数。。。
int fir=0; // 用于判断是否打印除第一个数字外的其他数字前的空格。
int brace=0; // 用于判断是否有左括号存在。
if(formula[i]=='+'||formula[i]=='-') //用于看第一个数字是否带正负号(如果前面没括号的话)
{
if(!judgeSet(formula[i+1]))
{
if(formula[i]=='-')
cout << formula[i];
i++;
getNumber(formula, i, fir);
}
}
while(i<formula.size())
{
if(judgeSet(formula[i]))
{
if(!S->next)
{
if(formula[i]=='(')
brace++;
push(S, formula[i]);
}
else
{
if(formula[i]=='(')
{
push(S, formula[i]);
brace++;
}
else if(formula[i]==')')
{
delBracket(S);
brace--;
}
else if(mp[formula[i]]>=mp[S->next->data] && brace==0)// 大于即新符号优先级低于旧符号
{
while(S->next&&mp[formula[i]]>=mp[S->next->data])
pop(S);
push(S, formula[i]);
}
else if(mp[formula[i]]<mp[S->next->data] && brace==0)
push(S, formula[i]);
else // brace>0即存在左括号
{
while(S->next&&mp[formula[i]]>=mp[S->next->data]&&S->next->data!='(')
pop(S);
push(S, formula[i]);
}
}
}
else//扫到数字
{
if((formula[i-1]=='+'||formula[i-1]=='-')&&judgeSet(formula[i-2])&&formula[i-2]!=')')
{
if(formula[i-1]=='-')
{
fir = 0;
pop(S);
}
else
delpop(S);//删除一个结点
getNumber(formula, i, fir);
continue;
}
getNumber(formula, i, fir);
continue;
}
i++;
}
// 如果还有剩余算符未打出来,全打出来
// 肖战(食不食油饼?)
SNode *p;
p = S->next;
while(p)
{
pop(S);
p = S->next;
}
return 0;
}