栈的实现从入门到熟练(题目练习)

使用STL实现栈

头文件:#include<stack>

定义:stack<int>a     stack<node>a

a.empty() 堆栈为空则返回真

a.pop()  移除栈顶元素

a.push() 在栈顶增加元素

a.size() 返回栈中元素数目

a.top() 返回栈顶元素

题目一(Can you get AC?)

这是一道十分简单的入门题

代码加详细解析:

#include<stdio.h>
#include<stack>
#include<string.h>
using namespace std;
int main()
{
	stack<char>a;
	char b[7];
	scanf("%s",b);
	int len = strlen(b);
	for (int i = 0; i < len; i++)
		a.push(b[i]);
	int p = 0;
	while (!a.empty()) {
		if (!a.empty() && a.top() == 'C') {
			a.pop();
			if (!a.empty() && a.top() == 'A')p = 1;
		}
		if(!a.empty()) a.pop();
	}
	if (p == 1)printf("Yes\n");
	else printf("No\n");
	return 0;
}

 题目二(小鱼的数字游戏)

 代码(太简单了,就不写注释了):

#include<stdio.h>
#include<stack>
using namespace std;
int main()
{
	stack<int>a;
	int p1, count = 0;

	while (scanf("%d", &p1) != EOF && p1 != 0) {
		a.push(p1);
		count++;
	}
	while (count--) {
		printf("%d ", a.top());
		a.pop();
	}
	return 0;
}

题目三(P4387 【深基15.习9】验证栈序列)

 题目描述

给出两个序列 pushed 和 poped 两个序列,其取值从 1 到 n(n<=100000)。已知入栈序列是pushed,如果出栈序列有可能是 poped,则输出 `Yes`,否则输出 `No`。为了防止骗分,每个测试点有多组数据。

 输入格式

第一行一个整数 q,询问次数。

接下来 q 个询问,对于每个询问:

第一行一个整数 n 表示序列长度;

第二行 n个整数表示入栈序列;

第三行 n 个整数表示出栈序列;

输出格式

对于每个询问输出答案。

样例输入 
2
5
1 2 3 4 5
5 4 3 2 1
4
1 2 3 4
2 4 1 3

样例输出 
Yes
No

思路:

这题的思路并没有想象中的那么简单,以第1个例子为例,输入5个数12345,题目的意思是说入栈的顺序是12345,但并没有说出栈的顺序一定是54321。而是你输入一个一个之后,也可以直接把它弹出去再输入,然后再弹再输入也可以。比如先输入123,再弹321再输入45再弹。这样弹出顺序就变成了32154。所以,输入的顺序是12345,但是弹出的顺序就不一定是54321,可以是其他的方式。题目的意思是说问有没有54321这种输出的方式,如果有的话就是yes,如果没有就是no。这个时候我们再来看第2个样例,它是1234的输入顺序。他想要出栈的顺序是2413,那么我们就可以先输入12,然后再把2弹出来。这个时候你再输入,因为他是要弹出4,再输入34之后他会把4弹出来,这个时候想要他再弹出1,但是实际上栈里面的数字是13了,那只能先弹3再弹1,那就不可能实现这个结果,所以他就是No。

#include<stdio.h>//使用了c++的stl
#include<stack>
using namespace std;
stack<int>g;
int main()
{
	int n, m;
	scanf("%d", &n);
	while (n--) {//多组输入
		int i; 
		int a[100100] = { 0 };
		int b[100100] = { 0 };
		scanf("%d", &m);//入栈元素个数
		for (i = 1; i <= m; i++)scanf("%d", &a[i]);
		for (i = 1; i <= m; i++)scanf("%d", &b[i]);
		int pos = 1;
		for (i = 1; i <= m; i++) {
			g.push(a[i]);//入栈
			while (!g.empty() && g.top() == b[pos]) {//按指定顺序出栈
				g.pop();
				pos++;
			}
		}
		if (g.empty()) printf("Yes\n");//如果栈内没有值,就说明有这种情况
		else printf("No\n");
		while (!g.empty())g.pop();//清空栈
	}
	return 0;
}

题目四(P5788 【模板】单调栈)

题目

注意不要时间超限了。

这是我第一次写的,时间超限了。

#include<stdio.h>
int a[3000050];
int main()
{
	int n;
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) {
		scanf("%d", &a[i]);
	}
	for (int i = 1; i <= n; i++) {
		int  f = 0;
		for (int j = i; j <n; j++) {
			if (a[i] < a[j]) {
				printf("%d ", j); 
				f = 1;
				break;
			}
		}
		if (f == 0)printf("0 ");
	}
	return 0;
}

用栈来写

#include<stdio.h>
#include<stack>
int a[4000005], b[4000005];
using namespace std;
int main()
{
	stack<int>g;//构建栈
	int n;//输入元素个数
	scanf("%d", &n);
	for (int i = 1; i <= n; i++)
	{
		scanf("%d", &a[i]);//输入元素
	}
	for (int i = n; i >= 1; i--)
	{
		while (!g.empty() && a[g.top()] <= a[i])
		{
			g.pop();
		}
		if (g.empty())
		{
			b[i] = 0;
		}
		else {
			b[i] = g.top();
		}
		g.push(i);
	}
	for (int i = 1; i <= n; i++)
	{
		printf("%d ", b[i]);
	}
	return 0;
}

题目五(日志分析)

额外补充(在代码中会遇到的知识点):

哈,这其实是我第一次写时用到的,但是提交的答案错误了。

1.exit 函数会终止程序的执行,并返回一个状态码给操作系统。这个状态码可以用来指示程序是正常结束还是遇到了错误。在 exit(1) 中,数字 1 通常表示一个错误状态。不同的数字可以表示不同类型的错误,这取决于特定的应用程序或上下文。例如,0 通常表示成功,而非零值(如 1)表示某种类型的错误。

实例:

#include <stdlib.h>  // for exit()  
  
int main() {  
    // ... 其他代码 ...  
      
    if (some_error_condition) {  
        // 如果遇到错误条件,退出程序并返回错误码1  
        exit(1);  
    }  
      
    // ... 其他代码 ...  
      
    return 0;  // 正常退出,返回状态码0  
}

辅助栈

要判断栈内的最大值,可以使用一个辅助栈。具体步骤如下:

  1. 创建一个空栈用于存储最大值。
  2. 遍历主栈中的每个元素,将其压入辅助栈中。
  3. 在压入辅助栈之前,检查当前元素是否大于辅助栈的栈顶元素。如果是,则将辅助栈的栈顶元素弹出,直到辅助栈的栈顶元素小于或等于当前元素,然后将当前元素压入辅助栈中。
  4. 遍历完主栈后,辅助栈中的栈顶元素即为主栈中的最大值

 

 思路:日志分析这道题题目挺简单的,就是三个条件,入栈出栈和查找。入栈的话,在入栈的同时还要找到最大值存入到另外一个栈里面。所以出栈的话,a栈和b栈应该是一起出站的。最后就是查找。

代码:

#include<stdio.h>
#include<stack>
using namespace std;
int main()
{
	stack<int>a,b;
	int n;
	scanf("%d", &n);
	while (n--) {
		int x, y;
		scanf("%d", &x);//x对应的是三种条件
		if (x == 0) {
			scanf("%d", &y);
			a.push(y);//a入栈
			if (b.empty() || a.top() > b.top())b.push(a.top());//找最大值
			else b.push(b.top());//b入栈
		}
		if (x == 1) {//出栈
			a.pop();
			b.pop();
		}
		if (x == 2) {//查找
			if (b.empty())printf("0\n");
			else {
				printf("%d\n",b.top());
			
			}
		}
	}
	return 0;
}

题目六(表达式求值)

思路:表达式求职这道题的思路很简单,但是不知道为什么我一直没有写出来,它最主要就是把带加号的都入进去。就比如说1+3×5+2,那么这个时候1先入栈,然后呢再把3入站,后面是乘以5嘛,要是乘5的话。我们就把3再出栈出栈之后再把3×5这个整体一起入栈。入栈之后我们再看后面是加2就直接把2再入栈,最后再把栈内所有的元素相加就可以了。

代码:

#include<stdio.h>
#include<string.h>
char a[1200000];
int x, cnt, ans;
int g[1000000];
int solve(int x, int g) {
	int ans = x * g;
	ans %= 10000;
	return ans;
}
int main() {
	int x = 0, last = 1;
	scanf("%s", a +1);
	int t = strlen(a +1);
	for (int i = 1; i <= t; i++) {
		if (a[i] >= '0' && a[i] <= '9') {
			x = x * 10 + a[i] - '0';
			x = x % 10000;
			if (i == t) {
				g[++cnt] = solve(x, last);

			}
		}
		else if (a[i] == '+') {
			g[++cnt] = solve(x, last);
			last = 1;
			x = 0;
		}
		else {
			last = solve(x, last);
			x = 0;
		}
	}
	for (int i = 1; i <= cnt; i++) {
		ans = ans + g[i];
		if (ans >= 10000)ans -= 10000;
	}
	printf("%d\n", ans);
	return 0;
}

  • 15
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值