任务描述
本关任务:熟练掌握STL
模板库中栈stack
的基本操作,并利用栈实现中缀表达式转化为前缀表达式。
相关知识
为了完成本关任务,你需要掌握:1.STL
模板栈的基本操作,2.中缀表达式转前缀表达式。
STL
模板栈的基本操作
C++ STL
模板的栈通过现有的序列容器来实现的,默认使用双端队列deque
的数据结构,也可以采用其他线性结构如:vector
或list
等,前提是提供栈的入栈、出栈、栈顶元素访问和判断是否为空的操作。stack
栈容器的C++
标准头文件为stack
。为了严格遵循栈元素后进先出原则,stack
不提供元素的任何迭代器操作,提供的基础操作及实例如下:
empty
判断栈是否为空,若空则返回true
,否则返回false
;size
返回栈表当前的大小,即栈表里元素的个数;top
返回栈顶元素push
将元素压入栈顶pop
移除栈顶元素
#include <iostream>
#include <algorithm>
#include <stack>
int main (){
std::stack<int> mystack; // 创建一个整型的栈表mystack
int sum (0);
for (int i=1;i<=10;i++) mystack.push(i); // 入栈
std::cout << mystack.size() <<'\n'; // 栈大小
while (!mystack.empty()){ // 判断栈是否为空
sum += mystack.top(); // 获取栈顶元素
mystack.pop(); // 移除栈顶元素
}
std::cout << "total: " << sum << '\n';
return 0;
}
中缀表达式转前缀表达式
算法思想:表达式中的对象为操作数和运算符,因此需要维护两个栈表:运算符栈和操作数(中间运算结果)栈,具体算法步骤如下。
- (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
转换为前缀表达式-+1*+2345
的过程如下:
编程要求
本关的编程任务是补全右侧代码片段main
中Begin
至End
中间的代码,具体要求如下:
- 读取中缀表达式,并基于栈的插入、删除等基本操作实现中缀表达式转化为前缀表达式,表达式中所有的操作数为单一的数字:
0~9
,运算符仅包含:+ - * ( )
。
测试说明
平台将自动编译补全后的代码,并生成若干组测试数据,接着根据程序的输出判断程序是否正确。
以下是平台的测试样例:
测试输入:1+((2+3)*4)-5
预期输出:-+1*+2345
输入格式:中缀表达式
输出格式:前缀表达式,末尾换行\n
//
// main.cpp
// step1
//
// 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 = s.size()-1; i>=0; i--)//从右到左扫描
{
L1:
if(s[i]>='0' && s[i]<='9')
{
s2.push(s[i]);
}
else
{
if(s[i]==')'||s1.empty())
{
s1.push(s[i]);
}
else if(s[i]=='(')
{
while(s1.top()!=')')
{
s2.push(s1.top());
s1.pop();
goto L1;
}
s1.pop();
}
else if(s1.top()=='*' && (s[i]=='-'||s[i]=='+'))
{
s2.push(s1.top());
s1.pop();
goto L1;
}
else if(s1.top()=='('&& (s[i]=='+'||s[i]=='-'||s[i]=='*'))
{
s2.push(s1.top());
s1.pop();
goto L1;
}
else
{
s1.push(s[i]);
}
}
}
while(!s1.empty())
{
s2.push(s1.top());
s1.pop();
}
while(!s2.empty())
{
printf("%c",s2.top());
s2.pop();
}
/********* End *********/
return 0;
}