9

在 c++ 中,如何打印出堆栈的内容并返回其大小?

std::stack<int>  values;
values.push(1);
values.push(2);
values.push(3);

// How do I print the stack?
4

6 回答 6

21

您可以制作堆栈的副本并一个接一个地弹出项目以转储它们:

#include <iostream>
#include <stack>
#include <string>

int main(int argc, const char *argv[])
{
    std::stack<int> stack;
    stack.push(1); 
    stack.push(3); 
    stack.push(7); 
    stack.push(19); 

    for (std::stack<int> dump = stack; !dump.empty(); dump.pop())
        std::cout << dump.top() << '\n';

    std::cout << "(" << stack.size() << " elements)\n";

    return 0;
}

输出

19
7
3
1
(4 elements)

在这里看到它:http: //liveworkspace.org/code/9489ee305e1f55ca18c0e5b6fa9b546f

于 2012-09-27T23:32:43.970 回答
5

std::stack和都是std::queue通用容器的包装器。该容器可作为protected成员访问c。使用c您可以获得对元素的有效访问;否则,您可以只复制堆栈或队列并破坏性地访问副本的元素。

使用示例c

#include <iostream>     // std::wcout, std::endl
#include <stack>        // std::stack
#include <stddef.h>     // ptrdiff_t
using namespace std;

typedef ptrdiff_t   Size;
typedef Size        Index;

template< class Elem >
Size nElements( stack< Elem > const& c )
{
    return c.size();
}

void display( stack<int> const& numbers )
{
    struct Hack
        : public stack<int>
    {
        static int item( Index const i, stack<int> const& numbers )
        {
            return (numbers.*&Hack::c)[i];
        }
    };

    wcout << numbers.size() << " numbers." << endl;
    for( Index i = 0;  i < nElements( numbers );  ++i )
    {
        wcout << "  " << Hack::item( i, numbers ) << endl;
    }
}

int main()
{
    stack<int>  numbers;
    for( int i = 1;  i <= 5;  ++i ) { numbers.push( 100*i ); }

    display( numbers );
}
于 2012-09-28T00:01:12.267 回答
4

std::stack 打印 a 的元素而不弹出它们的唯一方法是编写一个扩展的适配器std::stack这里是一个示例)。否则,您应该将堆栈替换为std::deque.

于 2012-09-27T23:43:46.907 回答
1

一种不使用“特殊技术”的简单方法是通过

递归

由于没有不能使用pop ()的成员函数std::stack<>等限制,我们可以使用以下递归算法。

算法:

  1. 基本情况:如果堆栈为空 => 返回。
  2. 弹出顶部元素并将其存储在变量中。
  3. 打印存储的值。
  4. 递归调用堆栈的其余元素。
  5. 再次将元素压入堆栈。

尽管进行了弹出操作,但堆栈不会丢失其元素,因为我们在打印堆栈的其余部分后以相同的顺序再次推送它们。

以下是上述算法的代码:

void printStack (std::stack <int> &values) {
    
    if (values.empty ()) {
        return;
    }

    int topElement = values.top ();
    values.pop ();

    std::cout << topElement << std::endl;

    printStack (values);

    values.push (topElement);
}

上述代码的输出:

3
2
1

这将从上到下打印元素。

如果要从下到上打印元素,只需切换递归调用和std::cout语句即可。

void printStack (std::stack <int> &values) {
    
    if (values.empty ()) {
        return;
    }

    int topElement = values.top ();
    values.pop ();

    printStack (values);

    std::cout << topElement << std::endl;

    values.push (topElement);
}

输出:

1
2
3

并且可以通过size ()成员函数std::stack<>来获取栈的大小。

std::cout << values.size () << std::endl;
于 2021-03-02T02:36:26.590 回答
0

嗯,一个将近10年的问题。无论如何,这里有一个额外的答案。

首先:堆栈的大小由 std::stack.size() 给出。

然后,在现代 C++ 中,越来越多地使用带有算法的 STL。因此,以下解决方案利用了这一点。前提是堆栈使用连续内存。目前这是有保证的。

输出是通过单线完成的。

请参见以下示例:

#include <vector>
#include <stack>
#include <iostream>
#include <algorithm>
#include <iterator>
#include <sstream>

using Number = int;
using UnderlyingContainer = std::vector<Number>;
using Stack = std::stack< Number, UnderlyingContainer>;

std::istringstream testData("5 8 1 4 9 3");

int main()
{
    // Put the test data onto the stack
    Stack stack{ UnderlyingContainer {std::istream_iterator<Number>(testData),std::istream_iterator<Number>()} };

    // Print the test data
    if (not stack.empty())
        std::copy(&stack.top() + 1 - stack.size(), &stack.top() + 1, std::ostream_iterator<Number>(std::cout, "\n"));

    return 0;
}

这是完全有效和可靠的代码。这里稍微解释一下。

我们想要输出数据,所以我们将其复制到 ostream_iterator。ostream_iterator 引用流(是的,您也可以放一个 open ofstream)和分隔符。也许您想使用“”。

副本的源是 2 个迭代器。而且,是的,指针是迭代器。而且,我们为 std::stack 使用了保证的连续内存。因此,我们只需计算 2 个指针并将它们交给 std::copy。

如果你想使用显式迭代器。开始了 。.

#include <vector>
#include <stack>
#include <iostream>
#include <algorithm>
#include <iterator>
#include <sstream>

using Number = int;
using UnderlyingContainer = std::vector<Number>;
using Stack = std::stack< Number, UnderlyingContainer>;

using StackIterator = const Number *;

std::istringstream testData("5 8 1 4 9 3");

int main()
{
    // Put the test data onto the stack
    Stack stack{ UnderlyingContainer {std::istream_iterator<Number>(testData),std::istream_iterator<Number>()} };

    // Print the test data
    // Get iterators
    StackIterator end = &stack.top() + 1;
    StackIterator begin = end - stack.size();

    if (not stack.empty())
        std::copy(begin, end, std::ostream_iterator<Number>(std::cout, "\n"));

    return 0;
}

因此,您可以为堆栈创建迭代器。但是,请注意:

std::stack 故意将其元素隐藏在引擎盖下。因此,如果您对数据进行写访问,我会将其视为设计错误。通过 const 指针/迭代器进行读取访问对我来说是可以的。但也许你应该更好地使用 std::vector 。. .

于 2019-06-10T11:56:21.217 回答
-1

http://www.cplusplus.com/reference/stl/stack/ 尺寸很容易使用:

cout << mystack.size();

对于其余部分,我在文档中没有看到任何内容,但是您应该在推送堆栈时打印堆栈的内容,或者有一个列表来记录元素只是为了打印它,不要完成测试后忘记删除它

于 2012-09-27T23:32:40.247 回答