文章目录
Contest100000605 - 《算法笔记》7.1小节——数据结构专题(1)->栈的应用
7.1 栈的应用
栈是一种先进后出的数据结构
常用函数
###(1)清空(clear)
###(2)获取栈内元素个数(size)
###(3)判空(empty)
###(4)进栈(push)
###(5)出栈(pop)
###(6)取栈顶元素(top)
栈的函数代码整理
//栈的函数代码整理
#include <iostream>
#include <cstdio>
void clear(){
TOP = -1;
}
int size(){
return TOP + 1;
}
bool empty(){
if(TOP == -1) return true;
else return false;
}
void push(int x){
st[++TOP] = x;
}
int top(){
return st[TOP];
}
int main() {
return 0;
}
例题codeup1918-简单计算器
见习题第一题
Codeup习题
Contest100000605 - 《算法笔记》7.1小节——数据结构专题(1)->栈的应用
链接: http://codeup.cn/contest.php?cid=100000605
1918-ProblemA-简单计算器
链接: http://codeup.cn/problem.php?cid=100000605&pid=0
思路:
//1918-ProblemA-简单计算器--法2
/*
中缀转后缀,计算后缀表达式
步骤一:中缀表达式转后缀表达式
设立一个操作符栈,用以临时存放操作符,根据要求将符合要求的操作符从栈顶弹出到后缀表达式中;
设立一个数组或队列,用以存放后缀表达式。从左到右扫描中缀表达式,如果遇到操作数,
就把操作数加入后缀表达式中;如果遇到操作符,根据后缀表达式的特性,就将其操作符与操作符栈
的栈顶操作符的优先级比较:如果高于栈顶元素的优先级,则压入操作符栈;若低于或等于,则将操作符栈的栈顶元素不断弹出到后缀表达式中,
直到其优先级大于栈顶元素。重复以上操作,直到中缀表达式扫描完毕,之后将操作符栈剩余的操作符依次弹入到后缀表达式中。
步骤二: 计算后缀表达式
从左到右扫描后缀表达式,如果是操作数,则入栈;如果是操作符,则连续弹出两个操作数,
然后进行操作符的操作生成的新操作数压入栈中,直到后缀表达式扫描完毕,最终答案就是栈中最后一个元素。
*/
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#include <cstdlib>
#include <stack>
#include <map>
#include <string>
using namespace std;
struct node{
double num;//数字
char op;//操作符
bool flag;//区分数字(1)操作符(0)
};
string str;
stack<node> s;//操作符栈
queue<node> q;//后缀表达式队列
map<char,int> opp;//操作符优先级映射
void change(){//中缀表达式转后缀表达式
double num;
node temp;
int len = str.length();
for(int i=0;i<len; ){
if(str[i] >= '0' && str[i] <= '9'){
temp.flag = 1;
temp.num = str[i++] - '0';//读取这个操作数的首位
while(i< len && str[i] >= '0' && str[i] <= '9'){//读取这个操作数
temp.num = temp.num * 10 + (str[i] - '0');
i++;
}
q.push(temp);
}
else{//操作符
temp.flag = 0;
//若低于或等于,则将操作符栈的栈顶元素不断弹出到后缀表达式中,
//直到其优先级大于栈顶元素
while(!s.empty() && opp[str[i]] <= opp[s.top().op]){
q.push(s.top());
s.pop();
}
//如果高于栈顶元素的优先级,则压入操作符栈
temp.op = str[i];
s.push(temp);
i++;
}
}
//如果操作符栈中还有操作符,就把它弹出到后缀表达式队列中
while(!s.empty()){
q.push(s.top());
s.pop();
}
}
//计算后缀表达式
double cal(){
double temp1,temp2;
node cur,temp;
while(!q.empty()){//后缀表达式非空
cur = q.front();//cur暂存队首元素
q.pop();
if(cur.flag == 1) s.push(cur);//操作数入栈
else{//操作符
temp2 = s.top().num;//弹出栈顶第一操作数
s.pop();
temp1 = s.top().num;//弹出第二操作数
s.pop();
temp.flag = 1;//临时记录操作数
if(cur.op == '+') temp.num = temp1 + temp2;//加法
else if(cur.op == '-') temp.num = temp1 - temp2;
else if(cur.op == '*') temp.num = temp1 * temp2;
else temp.num = temp1 / temp2;
s.push(temp);//将计算结果压入栈
}
}
return s.top().num;//最终数字栈最后一个数即结果
}
int main() {
opp['+'] = opp['-'] = 1;//设定操作符优先级
opp['*'] = opp['/'] = 2;
while(getline(cin,str),str != "0"){
for(string::iterator it = str.end();it!=str.begin();it--){
if(*it == ' ') str.erase(it);//去掉表达式中的空格
}
while(!s.empty()) s.pop();//初始化栈
change();
printf("%.2lf\n",cal());//计算后缀表达式的值
}
return 0;
}
1982ProblemB-ProblemE
链接: http://codeup.cn/problem.php?cid=100000605&pid=1
//1982-ProblemB-ProblemE
//栈的应用之括号匹配
#include <iostream>
#include <string>
#include <cstring>
#include <stack>
using namespace std;
string str;
void match(){
stack<char> bracket;//括号入栈
bool flag = 1;
for(int i = 0;i < str.length();i++){
if(str[i] == '(' || str[i] == '[' || str[i] == '{'){//左括号入栈
bracket.push(str[i]);
}
else{//进行匹配
if(bracket.empty()){
flag = 0;
break;
}
char temp;//暂存当前栈顶括号对应的符号,以便后续判断
if(str[i] == ')'){
if(bracket.top() != '('){
flag = 0;
break;
}
}
else if(str[i] == ']'){
if(bracket.top() != '['){
flag = 0;
break;
}
}
if(str[i] == '}'){
if(bracket.top() != '{'){
flag = 0;
break;
}
}
bracket.pop();
}
}
if(flag && bracket.empty()) cout<<"yes"<<endl;
else cout<<"no"<<endl;
}
int main(){
int n;
while(cin>>n){
while(n--){
cin>>str;
//去除表达式中非括号部分
for(string::iterator it = str.begin();it != str.end();it++){
if(*it != '(' && *it != ')' && *it != '[' && *it != ']' && *it != '{' && *it != '}'){
str.erase(it);
it--;//注意删除后it位置变化
}
}
match();
}
}
return 0;
}
栈小结
栈是一种先进后出的数据结构,有着很多应用,比如递归模拟,表达式求值,括号匹配等等;常用的函数有:清空(clear)、获取栈内元素个数(size)、判空(empty)、进栈(push)、出栈(pop)、取栈顶元素(top)等