实验3:栈、队列与递归

集美大学课程实验报告-实验3:栈、队列与递归

项目名称 内容
课程名称 数据结构
班级 网安2511
学号 202521336001
实验项目名称 栈和队列
上机实践日期 2026.04.05
上机实践时间 2学时

一、目的(本次实验所涉及并要求掌握的知识点)

  • 掌握STL中string的使用
  • 熟练掌握STL中栈(stack)和队列(queue)的基本使用
  • 掌握栈和队列的一些典型应用

二、实验内容与设计思想

题目1:栈的应用(符号配对)

函数相关伪代码

getline整行输入string类型的s
定义栈node
循环:
{
  char c=s[i]
  if (c找到'(','[','{')
    {
      node.push()
    }
     else if(c找到')',']','}')
        {
          判断:
          if(node.empty)
            {
                栈内没有匹配的符号,输出no并跳出循环
            }
          取栈顶元素top,为找到配对,cout<<top并cout<<no
          若匹配,弹出栈顶元素node.pop()
        }
}
if(node.empty)
  {
    全部匹配成功并弹出,cout<<yes;
  }else//失败
  {
    cout<<top<<endl;
    cout<<no;
  }

函数代码

#include <iostream>
#include <string>
#include <stack>
using namespace std;

int main() {
    string s;
    getline(cin, s);
    stack<char> node;
    for (size_t i = 0; i < s.length(); i++) {
        char c = s[i];
        if (c == '(' || c == '[' || c == '{') {
            node.push(c);
        }
        else if (c == ')' || c == ']' || c == '}') {
            if (node.empty()) {
                cout << "no" << endl;
                return 0;
            }
            char top = node.top();
            node.pop();
            if ((c == ')' && top != '(') ||
                (c == ']' && top != '[') ||
                (c == '}' && top != '{')) {
                cout << top << endl;
                cout << "no" << endl;
                return 0;
            }
        }
    }
    if (node.empty()) {
        cout << "yes" << endl;
    } else {
        char top = node.top();
        cout << top << endl;
        cout << "no" << endl;
    }
    return 0;
}

题目2:使用 stack 将递归转化为非递归程序

函数相关伪代码

函数 test_non_recursive():
    stack<int> s
    int x
    循环:
        输入 x
        如果 x == 0:
            跳出循环
        否则:
            s.push(x)
    sum = 0
    循环:
        如果 s 不为空:
            x = s.top()
            s.pop()
            sum += x
            输出 sum
        否则:
            跳出循环

函数代码

#include <iostream>
#include <stack>
using namespace std;

void test_non_recursive() {
    stack<int> s;
    int x;
    // 读取输入,直到输入0
    while (true) {
        cin >> x;
        if (x == 0) {
            break;
        }
        s.push(x);
    }
    int sum = 0;
    // 弹出栈顶,累加并输出
    while (!s.empty()) {
        x = s.top();
        s.pop();
        sum += x;
        cout << sum << endl;
    }
}

// 添加 main 函数
int main() {
    test_non_recursive();  // 调用你写的函数
    return 0;
}

题目3:队列的应用(银行业务队列)

函数相关伪代码

// 初始化两个队列,分别存储A窗口和B窗口的顾客
创建队列A  
创建队列B  
读取输入:第一个数为N,后面N个数为顾客编号序列  
遍历顾客编号序列:  
    如果编号为奇数,加入队列A  
    否则,加入队列B  

初始化结果列表result  
循环直到A和B都为空:  
    // 处理A窗口的业务(速度是B的2倍,即每轮先处理A的两个顾客,再处理B的一个)  
    如果A不为空:  
        取出A的第一个顾客,加入result  
        如果A不为空:  
            取出A的第一个顾客,加入result  
    如果B不为空:  
        取出B的第一个顾客,加入result  
    // 当两个窗口同时处理完(A处理2个,B处理1个)时,A的优先级更高已在上面的顺序保证(先处理A的两个)  

输出result中的顾客编号,用空格分隔(最后一个无多余空格)

函数代码

#include <iostream>
#include <queue>
#include <vector>

using namespace std;

int main() {
    int n;
    cin >> n;
    queue<int> queue_a, queue_b;
    for (int i = 0; i < n; i++) {
        int customer;
        cin >> customer;
        if (customer % 2 == 1) {
            queue_a.push(customer);  // 奇数去A窗口
        } else {
            queue_b.push(customer);  // 偶数去B窗口
        }
    }
    
    vector<int> result;
    
    while (!queue_a.empty() || !queue_b.empty()) {
        if (!queue_a.empty()) {
            result.push_back(queue_a.front());
            queue_a.pop();
            if (!queue_a.empty()) {
                result.push_back(queue_a.front());
                queue_a.pop();
            }
        }
        if (!queue_b.empty()) {
            result.push_back(queue_b.front());
            queue_b.pop();
        }
    }
    for (int i = 0; i < result.size(); i++) {
        if (i > 0) {
            cout << " ";
        }
        cout << result[i];
    }
    cout << endl;
    
    return 0;
}

三、实验使用环境(本次实验所使用的平台和相关软件)

  • 操作系统:Windows 10 专业版
  • 编程语言:C++
  • 开发工具Visual Studio 2022
  • 编译器:VS2022

四、实验步骤和调试过程(实验步骤、测试数据设计、测试结果分析)

题目1:符号配对

本机运行截图
image

PTA提交截图
image

题目2:使用 stack 将递归转化为非递归程序

本机运行截图
image

题目3:银行业务队列

本机运行截图
image

PTA提交截图
image


五、实验小结(实验中遇到的问题及解决过程、实验体会和收获)

遇到的问题及解决方法:

  1. 问题:程序崩溃找不到原因
    • 解决方法:使用打断点进行调试的方法。
  2. 问题:未检查队列是否为空,直接调用 queue.front()或 queue.pop()
    • 解决方法:在调用 front()/pop()前,必须通过 !queue.empty()判空;处理 A 窗口的“取2个元素”逻辑时,拆分为“先取1个(判空)→ 再取1个(再次判空)”。

实验体会和收获:

  • 掌握了string的使用
  • 了解stack和queue的基本使用
  • 学习了VS断点调试方法

六、附件(参考文献和相关资料)

  1. C++ Primer
  2. 实验3-栈与队列
posted @ 2026-04-06 00:43  Wujee  阅读(2)  评论(0)    收藏  举报