24年1.31总结(栈和双向队列)

用栈来计入表达式的值

遇乘号(说明两数相乘中乘号前的那个数已经被放入栈中,成为栈顶元素了)就将数乘栈顶元素再放进栈中(以前的栈顶元素要取出来然后再放进乘完后的元素),加号就直接放,因此栈中的数最后都是相加起来,

​
#include <iostream>
#include <stack>
using namespace std;
stack <int> x;//一个存数字并在最后把它们相加的栈
int main()
{
	int a,b;
	char c;
	pintf("%d",&a);//先输入一个数,以后符号+数字输入
	int m=10000;
	a=a%m;//必须的操作
	x.push(a);//压入栈中
	while(while("%c %d",&c,&b)!=EOF)
	{
		if(c=='*')//将*之前的数字与*之后的数字积存入 
		{
			a=x.top();//此时top顶的数就是相乘数中的一个数
			x.pop();
			x.push(a*b%m);//取两数之积的摸;
		}
		else//将b存入
			x.push(b);
	}
	a=0;
	while(x.size())//将所有数都加起来
	{
		a+=x.top();
		a%=m;//取模
		x.pop();
	}
	printf("%d",a);
	return 0;
}

​

括号匹配是使用栈解决的经典问题

建议要写代码之前要分析好有哪几种不匹配的情况,如果不动手之前分析好,写出的代码也会有很多问题。

先来分析一下 这里有三种不匹配的情况,

  1. 第一种情况,字符串里左方向的括号多余了,所以不匹配。
  2. 第二种情况,括号没有多余,但是括号的类型没有匹配上。
  3. 第三种情况,字符串里右方向的括号多余了,所以不匹配。

这里还有一些技巧,在匹配左括号的时候,右括号先入栈,就只需要比较当前元素和栈顶相不相等就可以了,比左括号先入栈代码实现要简单的多了!

#include<stdio.h>
#include<string.h>
int main()
{
	char a[300];int cnt1=0,cnt2=0;
    scanf("%s",a);
    a[strcspn(a, "\n")] = 0; 
	int t=strlen(a);int i; 
	for( i=0;i<t;i++){
		if(a[i]==')') cnt1++;
		if(cnt1>cnt2){
			printf("NO");//在整个式子中,左括号的数量累加的速度一定比右括号慢
			return 0; 
		}
		if(a[i]=='(')cnt2++;
	}
	if(cnt1==cnt2){
		printf("YES");
		
	} 
	else{
		printf("NO");
	}
	
	
	
 } 

双向队列

一、概述

deque(双端队列)是由一段一段的定量连续空间构成,可以向两端发展,因此不论在尾部或头部安插元素都十分迅速。 在中间部分安插元素则比较费时,因为必须移动其它元素。

二、定义及初始化

#include <deque> // deque属于std命名域的,因此需要通过命名限定,

deque<int> a; // 定义一个int类型的双端队列a

deque<int> a(10); // 定义一个int类型的双端队列a,并设置初始大小为10

deque<int> a(10, 1); // 定义一个int类型的双端队列a,并设置初始大小为10且初始值都为1

deque<int> b(a); // 定义并用双端队列a初始化双端队列b

deque<int> b(a.begin(), a.begin()+3); // 将双端队列a中从第0个到第2个(共3个)作为双端队列b的初始值
三、基本操作函数

3.1 容量函数
  • 容器大小:deq.size();
  • 容器最大容量:deq.max_size();
  • 更改容器大小:deq.resize();
  • 容器判空:deq.empty();
  • 减少容器大小到满足元素所占存储空间的大小:deq.shrink_to_fit();
3.3 删除函数
  • 头部删除元素:deq.pop_front();
  • 末尾删除元素:deq.pop_back();
  • 任意位置删除一个元素:deq.erase(iterator it);
  • 清空所有元素:deq.clear();

   
#include<bits/stdc++.h>
using namespace std;
deque<long long> g;//双向队列
long long k,x,j,n,op,m,i,t,w,y,a[3000005];
int main()
{
	scanf("%lld %lld %lld",&n,&m,&k);//人数  次数   范围 
	for(i=1;i<=n;i++)scanf("%lld",&a[i]);//输入
     sort(a+1, a+1+n);
	for(i=1;i<=n;i++)g.push_back(a[i]);//入队  先入小的(小的数在头部) 

	while(m--){
		scanf("%lld",&op);
		if(op==1){
			scanf("%lld",&x);//正移x 
			y+=x;
			while(!g.empty()){
        	w=g.back();//取得是尾部的大数
				if(w+y>k) g.pop_back();//如果此埴轮移动完超过k,就被淘汰了 (出队
				else  break;//执行这个代表该出队的都出了 
			}
			
		}
		else if(op==2){
			scanf("%lld",&x);//负移x 
			y-=x;
			while(!g.empty()) {
				w = g.front();//头部是小一点的数 
				if(w+y<-k)g.pop_front();//如果此埴轮移动完小于-k,也会被淘汰 (从队头弹出) 
				else	break;
			}
		}
		else if(op==3){
		printf("%lld\n",g.size()); 
		
		
	}
}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值