Contest100000602 - 《算法笔记》6.7小节——C++标准模板库(STL)介绍->stack的常见用法详解

文章目录

  • Contest100000602 - 《算法笔记》6.7小节——C++标准模板库(STL)介绍->stack的常见用法详解
  • 6.7 stack的常见用法详解
    • 1. stack的定义
    • 2. stack容器内元素的访问
    • 3. stack常用函数实例解析
      • (1)push()
      • (2)top()
      • (3)pop()
      • (4)empty()
      • (5)size()
      • stack函数整合代码
    • 4. stack的常见用途
  • Codeup习题
    • 1918-ProblemA-简单计算器
    • 1982-ProblemB-ProblemE
  • stack小结

Contest100000602 - 《算法笔记》6.7小节——C++标准模板库(STL)介绍->stack的常见用法详解

6.7 stack的常见用法详解

stack即栈,是一种先进后出的容器,区别于queue;

1. stack的定义

在这里插入图片描述

2. stack容器内元素的访问

只能访问栈顶
在这里插入图片描述

3. stack常用函数实例解析

(1)push()

(2)top()

(3)pop()

Contest100000602 - 《算法笔记》6.7小节——C++标准模板库(STL)介绍->stack的常见用法详解_第1张图片

(4)empty()

在这里插入图片描述

(5)size()

在这里插入图片描述

stack函数整合代码

//stack常用函数代码整合 
#include <iostream>
#include <stack>
using namespace std;

 
int main() {
	stack<int> st;
	//---1、2、3---push()、top()、pop() 
	for(int i = 1;i <= 5;i++){
		st.push(i);//将i压入栈 
	}
	cout<<"入栈12345的栈顶为:";
	cout<<st.top()<<endl;
	for(int i = 1;i <= 3;i++){
		st.pop();
	}
	cout<<"出栈3个元素后栈顶为:";
	printf("%d\n",st.top());
	//---4---empty()
	cout<<"此时栈为空吗?"<<endl;
	if(st.empty() == true)printf("Empty\n");
	else	printf("Not Empty\n");
	//---5---size()
	cout<<"此时队列大小为:"<<st.size()<<endl;

	return 0;
}


4. stack的常见用途

在这里插入图片描述

Codeup习题

Contest100000602 - 《算法笔记》6.7小节——C++标准模板库(STL)介绍->stack的常见用法详解
链接: http://codeup.cn/contest.php?cid=100000602

1918-ProblemA-简单计算器

链接:http://codeup.cn/problem.php?cid=100000602&pid=0
法一:建立一个栈,将数字依次存入栈中,遇到乘除则运算后再存入栈,
遇到减号变成相反数入栈,最终求和数字栈即可得到表达式的值
%50的错误率,未能通过OJ

//1918-ProblemA-简单计算器
/*
建立一个栈,将数字依次存入栈中,遇到乘除则运算后再存入栈,
遇到减号变成相反数入栈,最终求和数字栈即可得到表达式的值 
*/
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <stack>
using namespace std;

int main() {
	char str[210];char num[210];
	char symbol[4]={'*','/','+','-'};
	stack<double> cal;
	while(cin.getline(str,210)){
		int len = strlen(str);
		if(len == 1 && str[0] == '0')	break;
		int flag = 2,count = 0;//flag判断加减乘除,初始化为2,因为第一个数直接存进去 
		for(int i=0;i<len;i++){
			int flag2 = 0;//flag2用来区分数字与符号
			if(str[i]==' ')	continue;//特别注意空格的处理
			if(str[i] >= '0' && str[i] <= '9'){
				num[count++] = str[i];
				flag2 = 1;//flag2==1表示为数字 
			} 
			if(flag2==0 || i==len-1){
				num[count] = '\0';//一个数字的结束
				double n = atoi(num);//将数字字符转换为数 
				count = 0;
				if(flag == 0){//乘法 
					double m = cal.top();
					n = n * m;
					cal.pop();
					cal.push(n);
				}
				else if(flag == 1){//除法 
					double m = cal.top();
					n = m/n;
					cal.pop();
					cal.push(n);
				} 
				else if(flag == 2){//加法 
					cal.push(n);
				} 
				else if(flag == 3){//减法 
					cal.push(-n);
				} 
				//判断运算数符号
			//	char symbol[4]={'*','/','+','-'};
				if(str[i] == '*'){
					flag = 0;
				}
				else if(str[i] == '/'){
					flag = 1;
				}
				else if(str[i] == '+'){
					flag = 2;
				}
				else if(str[i] == '-'){
					flag = 3;
				}
			}
		}
		double alcount = 0;
		//对栈内剩余元素相加求和 
		while(!cal.empty()){
			alcount += cal.top();
			cal.pop();
		}
		printf("%.2lf\n",alcount);
	}
	return 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;
}

	

1982-ProblemB-ProblemE

链接:http://codeup.cn/problem.php?cid=100000602&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;
}

	

stack小结

stack即栈,是一种先进后出的容器,区别于queue;常用函数为push()、top()、pop()、empty()、)size();多用来模拟递归,具体应用与表达式求值、括号匹配等

你可能感兴趣的:(算法笔记刷题笔记)