Stack (30)

题目描述

Stack is one of the most fundamental data structures, which is based on the principle of Last In First Out (LIFO).  The basic operations include Push (inserting an element onto the top position) and Pop (deleting the top element).  Now you are supposed to implement a stack with an extra operation: PeekMedian -- return the median value of all the elements in the stack.  With N elements, the median value is defined to be the (N/2)-th smallest element if N is even, or ((N+1)/2)-th if N is odd.

输入描述:

Each input file contains one test case.  For each case, the first line contains a positive integer N (<= 105).  Then N lines follow, each contains a command in one of the following 3 formats:

Push key
Pop
PeekMedian

where key is a positive integer no more than 105.


输出描述:

For each Push command, insert key into the stack and output nothing.  For each Pop or PeekMedian command, print in a line the corresponding returned value.  If the command is invalid, print "Invalid" instead.

输入例子:

17
Pop
PeekMedian
Push 3
PeekMedian
Push 2
PeekMedian
Push 1
PeekMedian
Pop
Pop
Push 5
Push 4
PeekMedian
Pop
Pop
Pop
Pop

输出例子:

Invalid
Invalid
3
2
2
1
2
4
4
5
3
Invalid


multiset和set一样,都是自动以升序将插入元素进行排序。

与set不同的是,multiset不去重。


设一个中值变量mid,Push时,如果数小于等于中值,插入s1(multiset)数组,否则插入s2(multiset)数组。

每次Pop或Push后,需保持s1数组与s2数组元素基本相等(若s1.size()<s2.size(),将s2数组的第一个元素给s1。若s1.size()>s.size()+1,将s1数组的最后一个元素给s2)。并且,若s1数组非空,则将中值mid更新为s1数组的最后一个元素。


我的代码:

#include<iostream>
#include<set>
#include<string.h>
#include<stack>
using namespace std;
multiset<int>s1,s2;
int n,m,mid=999999;
void midst()
{
    multiset<int>::iterator it;
    if(s1.size()<s2.size())
    {
        it=s2.begin();
        s1.insert(*it);
        s2.erase(it);
    }
    if(s1.size()>s2.size()+1)
    {
        it=s1.end();
        it--;
        s2.insert(*it);
        s1.erase(it);
    }
    if(!s1.empty())
    {
        it=s1.end();
        it--;
        mid=*it;
    }
}
int main()
{
    stack<int>s;
    char x[20];
    scanf("%d%*c",&n);
    while(n--)
    {
        scanf("%s",x);
        if(strcmp(x,"Pop")==0)
        {
            if(s.empty()) puts("Invalid");
            else
            {
                int t=s.top();
                printf("%d\n",t);
                s.pop();
                if(t<=mid) s1.erase(s1.find(t));
                else s2.erase(s2.find(t));
                midst();
            }
        }
        else if(strcmp(x,"PeekMedian")==0)
        {
            if(s.empty()) puts("Invalid");
            else printf("%d\n",mid);
        }
        else if(strcmp(x,"Push")==0)
        {
            scanf("%d%*c",&m);
            s.push(m);
            if(m<=mid) s1.insert(m);
            else s2.insert(m);
            midst();
        }
    }
    return 0;
}

### STL Stack 的基本概念 `std::stack` 是 C++ 标准模板库(STL)中的容器适配器之一,它提供了一种后进先出(Last In First Out, LIFO)的数据结构。尽管 `std::stack` 提供了栈的功能,但它本身并不是一个独立的容器,而是基于其他底层容器实现的,比如 `std::deque` 或 `std::vector`。 默认情况下,`std::stack` 使用的是 `std::deque` 作为其底层容器[^1]。然而,也可以通过指定不同的底层容器来改变它的行为。 --- ### STL Stack 的主要成员函数 以下是 `std::stack` 中常用的操作方法: #### 构造与销毁 - **构造**: 可以显式指定底层容器类型。 - **析构**: 自动释放资源。 #### 数据操作 - **push(element)**: 向栈顶添加一个新元素。 - **pop()**: 移除栈顶元素(不返回被移除的值)。 - **top()**: 返回栈顶元素的引用(不会删除该元素)。如果栈为空,则调用此函数的行为未定义。 #### 状态查询 - **empty()**: 如果栈为空则返回 true,否则返回 false。 - **size()**: 返回当前栈中元素的数量(注意:某些旧版本编译器可能不支持 size 方法)。 这些功能使得 `std::stack` 成为了处理需要遵循 LIFO 原则场景的理想工具。 --- ### 示例代码展示 下面是一个简单的例子,演示如何使用 `std::stack` 来存储整数并执行一些基本操作: ```cpp #include <iostream> #include <stack> int main() { std::stack<int> s; // Push elements onto the stack s.push(10); s.push(20); s.push(30); // Display top element std::cout << "Top element is: " << s.top() << '\n'; // Pop top element s.pop(); // Check if stack becomes empty after popping all elements while (!s.empty()) { std::cout << "Popped: " << s.top() << '\n'; s.pop(); } return 0; } ``` 上述程序展示了向栈中压入三个整数值,并逐一弹出的过程。每次弹出前都会打印当前栈顶的内容。 --- ### 底层容器的选择影响性能 虽然大多数时候无需关心具体使用的底层容器是什么,但在特定应用场景下选择合适的底层容器可能会带来显著差异。例如: - 当频繁插入/删除操作发生在一端时,`std::deque` 更加高效; - 若内存连续性和随机访问速度更重要的话,则应考虑采用 `std::vector` 作为基础容器。 可以通过如下方式自定义底层数组类型: ```cpp std::stack<int, std::vector<int>> myStackWithVectorBase; ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值