栈与队列相关题型

栈与队列相关题型

基础知识

栈:后进先出(LIFO-last in first out):最后插入的元素最先出来。

使用栈,要先包含头文件 : #include

定义栈,以如下形式实现: stack s; 其中Type为数据类型(如 int,float,char等)。

栈的主要操作:
s.push(item); //将item压入栈顶
s.pop(); //删除栈顶的元素,但不会返回
s.top(); //返回栈顶的元素,但不会删除
s.size(); //返回栈中元素的个数
s.empty(); //检查栈是否为空,如果为空返回true,否则返回false
//栈操作举例:
#include<iostream>
#include<stack>
#include<queue>
using namespace std;
 
void main()
{
    stack<int> s;
    int num;
 
    cout<<"------Test for Stack-------"<<endl;
    cout<<"Input number:"<<endl;
    
    while(cin>>num)
    {
        s.push(num);
    }
 
    cout<<"The Stack has "<<s.size()<<" numbers.They are:"<<endl;
    while(!s.empty())
    {
        cout<<s.top()<<" ";
        s.pop();
    }
    cout<<"\nNow the size is "<<s.size()<<endl;
    system("Pause");
}

运行截图

在这里插入图片描述

队列

队列:先进先出(FIFO-first in first out):最先插入的元素最先出来。

使用队列,要先包含头文件 : #include

定义队列,以如下形式实现: queue q; 其中Type为数据类型(如 int,float,char等)。

队列的主要操作:
q.push(item) //将item压入队列尾部
q.pop() //删除队首元素,但不返回
q.front() //返回队首元素,但不删除
q.back() //返回队尾元素,但不删除
q.size() //返回队列中元素的个数
q.empty() //检查队列是否为空,如果为空返回true,否则返回false
//队列操作举例
#include<iostream>
#include<stack>
#include<queue>
using namespace std;
 
void main()
{
    queue<int> q;
    int num;
 
    cout<<"------Test for Queue-------"<<endl;
    cout<<"Input number:"<<endl;
    while(cin>>num)
    {
        q.push(num);
    }
    cout<<"Now the Queue has "<<q.size()<<" numbers."<<endl;
    cout<<"The first is "<<q.front()<<endl;
    cout<<"The last is "<<q.back()<<endl;
    cout<<"All numbers:"<<endl;
    while(!q.empty())
    {
        cout<<q.front()<<" ";
        q.pop();
    }
    cout<<"Now the Queue has "<<q.size()<<" numbers."<<endl;
    system("Pause");
}

运行截图

在这里插入图片描述

栈与队列的区别

在这里插入图片描述

7-3 银行业务队列简单模拟

https://pintia.cn/problem-sets/1628020702584594432/exam/problems/1628020809572896770

#include<bits/stdc++.h>

using namespace std;
const int N = 1e3+10;
int a[N],cnt;
int main() {
    queue<int> A;
    queue<int> B;
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++) {
        int data;
        cin >> data;
        // !(data & 1):即data 为偶数 等同于 data % 2 == 0
        if (!(data & 1)) B.push(data);
        else A.push(data); 
    }
    while (A.size() && B.size()) {
        if (A.size() >= 2) {
            a[cnt++] = A.front();
            A.pop();
            a[cnt++] = A.front();
            A.pop();
        }// A窗口处理速度是B窗口的两倍
        else {
            a[cnt++] = A.front();
            A.pop();
        }
        a[cnt++] = B.front();
        B.pop();
    }
    // B窗口无人,A窗口有人的情况
    while (A.size()) {
        a[cnt++] = A.front();
        A.pop();
    }
    // A窗口无人,B窗口有人的情况
    while (B.size()) {
        a[cnt++] = B.front();
        B.pop();
    }
    for (int i = 0; i < cnt; i++) {
        if (i != cnt - 1) cout << a[i] << " ";
        else cout << a[i];
    }
}

7-4 表达式转换

https://pintia.cn/problem-sets/1628020702584594432/exam/problems/1628020809572896771

在这里插入图片描述


#include<bits/stdc++.h>

using namespace std;

int main() {
	string s;
	cin >> s;
	stack<char> sk;// 用来存储运算符
	bool flag = true;//作为一个标志,表示字符一定为数字
	for (int i = 0; i < (int)s.size(); i++) {
		if (isdigit(s[i])) {// isdigit 函数:用来判断字符是否为数字
			if (flag) {
				cout << s[i];
				flag = false;
				continue;
			}
			if (!isdigit(s[i-1])) {
				cout << " " << s[i];
			}
			else if (isdigit(s[i-1]) || isdigit(s[i+1])) cout << s[i];
		}
		else if (sk.empty()) {
			if (s[i] == '+' && i == 0) continue; //+25
			else if (s[i] == '-' && i == 0) {// -25
				cout << s[i];
				flag = true;// 表示当前字符的下一个字符一定是数字
				continue;
			}
			else if (s[i] == '.') { //2.5
				cout << s[i];
				flag = true;// 当前字符的下一个字符一定为数字
				continue;
			}
			sk.push(s[i]);
		}
		else if (s[i] == '*' || s[i] == '/') {
            // 运算符高于栈顶元素,直接加入栈
			if (sk.top() == '+' || sk.top() == '-' || sk.top() == '(') sk.push(s[i]);
			else {// 否则说明当前字符运算符级别与栈顶元素级别相同
				if (i) cout << " ";
				cout << s[i];
			}
		}
		else if (s[i] == '+' || s[i] == '-') {
			if (s[i-1] == '(' && s[i] == '+') continue; // (+25)
			else if (s[i-1] == '(') {// (-25)
				cout << s[i];
                  flag = true;
				continue;
			}
            // 栈顶元素运算级别大于当前符号级别,输出栈顶元素
			while (!sk.empty() && (sk.top() == '*' || sk.top() == '/')) {
				if (i) cout << " ";
				cout << sk.top();
				sk.pop();
			}
			if (sk.empty() || sk.top() == '(') sk.push(s[i]); // 栈内无元素的情况
			else {
				if (i) cout << " ";
				cout << s[i];
			}
		}
		else if (s[i] == '(') sk.push(s[i]);
		else if (s[i] == ')') {
			while (sk.top() != '(') {
				if (i) cout << " ";
				cout << sk.top();
				sk.pop();
			}
			sk.pop(); // 弹出'('
		}
		else if (s[i] == '.') {
			cout << s[i];
			flag = true; // 2.5
		}
	}
    // 如果栈内还有元素,直接输出即可
	while (sk.size()) {
		cout << " " << sk.top();
		sk.pop();
	}
}

扩展:中缀转前缀思路

      *(1) 初始化两个栈:运算符栈S1和储存中间结果的栈S2;
     * (2) 从右至左扫描中缀表达式;
     * (3) 遇到操作数时,将其压入S2;
     * (4) 遇到运算符时,比较其与S1栈顶运算符的优先级:
     * (4-1) 如果S1为空,则直接将此运算符入栈;
     * (4-2) 否则,若优先级比栈顶运算符的较高或相等(后缀表达式中是较高,没有相等)或栈顶运算符为右括号“)”,
        也将运算符压入S1;
     * (4-3) 否则,将S1栈顶的运算符弹出并压入到S2中,再次转到(4-1)与S1中新的栈顶运算符相比较;
     * (5) 遇到括号时:
     * (5-1) 如果是右括号“)”,则直接压入S1;
     * (5-2) 如果是左括号“(”,则依次弹出S1栈顶的运算符,并压入S2,直到遇到右括号为止,此时将这一对括号丢弃
     * (6) 重复步骤(2)至(5),直到表达式的最左边;
     * (7) 将S1中剩余的运算符依次弹出并压入S2;
     * (8) 依次弹出S2中的元素并输出,结果即为中缀表达式对应的前缀表达式。

7-58 堆栈模拟队列

https://pintia.cn/problem-sets/1628020702584594432/exam/problems/1628020809572896825

#include<bits/stdc++.h>
using namespace std;

int main() {
    int n,m;
    cin >> n >> m;
    stack<int> s1,s2;
    if (n < m) swap(n,m);
    // 默认将s1设置为大容量的栈(容量为n),s2设置为小容量的栈(容量为m)
    char c;
    while (cin >> c) {
        if (c == 'T') break;
        else if (c == 'A') {
            int data;
            cin >> data;
            if ((int)s2.size() < m) s2.push(data);
            else {
                if (s1.empty()) {
                    while (s2.size()) {
                        s1.push(s2.top());
                        s2.pop();
                    }
                    s2.push(data);
                }
                else cout << "ERROR:Full" << '\n';
            }
        }
        else {
            if (s1.size()) {
                cout <<s1.top() << '\n';
                s1.pop();
            }
            else {
                if(s2.size()) {
                	while (s2.size()) {
                		s1.push(s2.top());
                		s2.pop();
                	}
                	cout << s1.top() << '\n';
                	s1.pop();
                }
                else cout << "ERROR:Empty" << '\n';
            }
        }
    }
}

7-62 windows消息队列

https://pintia.cn/problem-sets/1628020702584594432/exam/problems/1628020809572896829

#include<bits/stdc++.h>

using namespace std;
typedef pair<int,string> PII;

int main() {
    map<int,string> mp;
    int n;
    cin >> n;
    priority_queue<PII,vector<PII>,greater<PII>> que; // 优先队列,默认为大顶堆,greater<>可以转化为小顶堆
    while (n--) {
        string s;
        cin >> s;
        if (s == "PUT") {
            string s1;
            int a;
            cin >> s1 >> a;
            que.push(make_pair(a,s1));
        }
        else {
            if (que.size()) {
                cout << que.top().second << '\n';
                que.pop();
            }
            else cout << "EMPTY QUEUE!" << '\n';
        }
    }
}

7-98 出栈序列的合法性

https://pintia.cn/problem-sets/1628020702584594432/exam/problems/1628020809577091100

#include<bits/stdc++.h>

using namespace std;
int m,n,k;

bool isValid() {
    int t = 1;
    stack<int> sk;
    bool flag = true;
    for (int i = 1; i <= n; i++) {
        int data;
        cin >> data;
        if (t < data) {
            for (int j = t; j <= data; j++) {
                sk.push(j);
            }
            t = data + 1;
            if (sk.size() > m) flag = false;
        }
        if (data == t) {
            t++;
            continue;
        }
        if (!sk.empty() && data == sk.top()) {
            sk.pop();
            continue;
        }
        if (data < t)flag = false;
    }
    if (flag) return true;
    else return false;
}
int main() {
    cin >> m >> n >> k;
    while (k--) {
        if (isValid()) puts("YES");
        else puts("NO");
    }
}

天梯赛3 括号匹配

https://pintia.cn/problem-sets/1642514333126778880/exam/problems/1642514395693215752

#include<bits/stdc++.h>

using namespace std;

bool isValid(string s) {
	stack<char> sk;
	for (int i = 0; i < (int)s.size(); i++) {
		if (s[i] == '(') sk.push(')');
		else if (s[i] == '[') sk.push(']');
		else if (s[i] == '{') sk.push('}');
		else if (sk.empty()) return cout << "Extra right brackets",0;
		else if (s[i] != sk.top()) return cout << "Brackets not match",0;
		else if (s[i] == sk.top()) sk.pop();
	}
	if (sk.size()) return cout << "Extra left brackets",0;
	return true;
}

int main() {
	string s;
	cin >> s;
	if (isValid(s)) {
		cout << "Brackets match" << '\n';
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

-Gaojs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值