任务描述
本关任务:熟练掌握STL
模板库中栈stack
的基本操作,并利用栈实现中缀表达式转化为后缀表达式。
相关知识
为了完成本关任务,你需要掌握:1.中缀表达式转后缀表达式。
中缀表达式转后缀表达式
与转换为前缀表达式相似,遵循以下步骤:
- (1) 初始化两个栈:运算符栈
S1
和储存中间结果的栈S2
; - (2) 从左至右扫描中缀表达式;
- (3) 遇到操作数时,将其压入
S2
; - (4) 遇到运算符时,比较其与
S1
栈顶运算符的优先级: - (4-1) 如果
S1
为空,或栈顶运算符为左括号(
,则直接将此运算符入栈; - (4-2) 否则,若优先级比栈顶运算符的高,也将运算符压入
S1
(注意转换为前缀表达式时是优先级较高或相同,而这里则不包括相同的情况); - (4-3) 否则,将
S1
栈顶的运算符弹出并压入到S2
中,再次转到(4-1)与S1
中新的栈顶运算符相比较; - (5) 遇到括号时:
- (5-1) 如果是左括号
(
,则直接压入S1
; - (5-2) 如果是右括号
)
,则依次弹出S1
栈顶的运算符,并压入S2
,直到遇到左括号为止,此时将这一对括号丢弃; - (6) 重复步骤(2)至(5),直到表达式的最右边;
- (7) 将
S1
中剩余的运算符依次弹出并压入S2
; - (8) 依次弹出
S2
中的元素并输出,结果的逆序即为中缀表达式对应的后缀表达式(转换为前缀表达式时不用逆序)。
例如,将中缀表达式1+((2+3)*4)-5
转换为后缀表达式123+4*+5-
的过程如下:
编程要求
本关的编程任务是补全右侧代码片段main
中Begin
至End
中间的代码,具体要求如下:
- 读取中缀表达式,并基于栈的插入、删除等基本操作实现中缀表达式转化为后缀表达式,表达式中所有的操作数为单一的数字:
0~9
,运算符仅包含:+ - * ( )
。
测试说明
平台将自动编译补全后的代码,并生成若干组测试数据,接着根据程序的输出判断程序是否正确。
以下是平台的测试样例:
测试输入:1+((2+3)*4)-5
预期输出:123+4*+5-
输入格式:中缀表达式
输出格式:后缀表达式,末尾换行\n
//
// main.cpp
// step2
//
// Created by ljpc on 2018/8/31.
// Copyright © 2018年 ljpc. All rights reserved.
//
#include <iostream>
#include <stack>
#include <cstring>
#include <algorithm>
using namespace std;
int main(int argc, const char * argv[]) {
// 请在这里补充代码,完成本关任务
/********* Begin *********/
string s;
stack<char> s1;
stack<char> s2;
cin >> s;
for ( int i = 0; i<s.size(); i++)// 从左到右扫描
{
L1:
if(s[i]>='0' && s[i]<='9')
{
s2.push(s[i]);
}
else
{
if(s[i]=='('||s1.empty()||s1.top()=='(')
{
s1.push(s[i]);
}
else if(s[i]==')')
{
while(s1.top()!='(')
{
s2.push(s1.top());
s1.pop();
}
s1.pop();
}
else if((s1.top()=='+'||s1.top()=='-') && s[i]=='*')
{
s1.push(s[i]);
}
else
{
s2.push(s1.top());
s1.pop();
goto L1;
}
}
}
while(!s1.empty())
{
s2.push(s1.top());
s1.pop();
}
char a[s2.size()];
int len=s2.size();
for(int i=s2.size()-1;i>=0;i--)// 因为要逆序输出,所以先把栈逆序存在一个数组中
{
a[i] = s2.top();
s2.pop();
}
for(int j=0;j<len;j++)
{
printf("%c",a[j]);
}
/********* End *********/
return 0;
}