NOI题目地址( 3.3数据结构之栈 ):http://noi.openjudge.cn/ch0303/
1696:逆波兰表达式
分析:
逆波兰表达式计算
用一个栈来存储数字,从右向左遍历表达式
- 遇到数字就压栈
- 遇到操作符就弹出栈中的两个数字计算并压栈
最后栈中剩余的数字就是我们要的结果
- Tip
这里计算的是前缀表达式,如果计算后缀表达式,将从右向左遍历改为从左向右遍历,修改带有次序的运算符如’/’的运算数的顺序(入栈次序与前序正好相反)。
AC题解:
#include <stack>
#include <iostream>
#include <iomanip>
#include <math.h>
using namespace std;
void cal(string param, stack<double> &num);
void bolan(string ¶m, stack<double> &num)
{
// 遇到数字就入栈
if (param != "+"&¶m != "*"&¶m != "-"&¶m != "/")
{
num.push(atof(param.c_str()));
}
// 遇到操作符就计算,并将结果入栈
else
{
cal(param, num);
}
}
void cal(string param, stack<double> &num)
{
double num1 = num.top();
num.pop();
double num2 = num.top();
num.pop();
if (param == "+")
{
num.push(num1 + num2);
}
if (param == "-")
{
num.push(num1 - num2);
}
if (param == "*")
{
num.push(num1 * num2);
}
if (param == "/")
{
num.push(num1 / num2);
}
// cout<<"cal result:"<<num.top()<<endl;
}
int main()
{
stack<double> num;
string command;
getline(cin, command);
int index1 = 0, index2 = command.length()-1;
// 从右向左遍历表达式 获取操作符和数字
for (int i = command.length()-1; i>=0; i--)
{
if (command[i] == ' ' || i == 0)
{
if(i==0) index1 = 0; else index1 = i+1;
string param = command.substr(index1, index2-index1+1);
// cout << index1 << " " << index2 << " #" << param << endl;
index2 = i-1;
bolan(param, num);
}
}
cout<<fixed<<setprecision(6)<<num.top()<<endl;
}
3340:RPN Calculator
分析:
题意
- 有一串初始值,称之为memory
- 每次计算出后缀表达式的值,替换掉这串初始值中的最小值
- 按照每行10个数的格式输出memory中的值
难点
后缀表达式的计算
用一个栈来存储数字,从左向左右遍历表达式
遇到数字就压栈
遇到操作符就弹出栈中的两个数字计算并压栈
最后栈中剩余的数字就是我们要的结果如何高效的找到最小值并替换?
这里使用了C++ STL priority_queue(优先队列),优先队列本质是一个堆,每次操作堆顶即可。
AC题解:
#include <stack>
#include <iostream>
#include <iomanip>
#include <math.h>
#include <vector>
#include <algorithm>
#include <sstream>
#include <queue>
using namespace std;
void cal(string param, stack<double> &num);
void bolan(string ¶m, stack<double> &num)
{