Một số thú vị với ngăn xếp thể hiện các phương pháp khác nhau để nhận giá trị vào ngăn xếp từ một vùng chứa khác.
Giả sử chúng tôi cung cấp một định nghĩa thích hợp cho:
template<class T, class Container>
auto stack_pusher(std::stack<T, Container>& stack);
Sau đó chúng tôi có thể viết:
int main()
{
using namespace std;
// construct an initial vector
vector<int> init { 7,6 };
// construct a stack using a copy of the initial vector's elements
// note that the stack's storage is automatically deduced
stack<int> stack1 { { begin(init), end(init) } };
// construct a stack directly from a container initialised with an initialiser list
stack<int> stack2 { { 3,4,5 } };
// another vector
vector<int> myvector { 1, 2, 3, 4, 5, 6, 7, 8 };
// copy vector onto stack using a forward iterator
copy(begin(myvector),
end(myvector),
stack_pusher(stack1));
// copy vector onto stack using a reverse iterator
copy(rbegin(myvector),
rend(myvector),
stack_pusher(stack2));
// display the stacks
while (stack1.size() or stack2.size())
{
// function to encode an optional T as a string
auto encode = [](const auto& opt)
{
return opt ? std::to_string(opt.value()) : std::string("*");
};
// function to pop a value from a stack if it's not empty.
// return an optional
auto maybe_pop = [](auto& stack)
{
using element_type = std::decay_t<decltype(stack.top())>;
boost::optional<element_type> result;
if (stack.size()) {
result = stack.top();
stack.pop();
}
return result;
};
cout
<< encode(maybe_pop(stack1))
<< "\t"
<< encode(maybe_pop(stack2)) << endl;
}
return 0;
}
mà đầu ra sẽ là:
8 1
7 2
6 3
5 4
4 5
3 6
2 7
1 8
6 5
7 4
* 3
Dưới đây là danh sách đầy đủ (C++ 14):
#include <iostream>
#include <stack>
#include <vector>
#include <deque>
#include <iterator>
#include <utility>
#include <boost/optional.hpp>
// an iterator that pushes values onto a stack
template<class Stack>
struct push_iterator
: std::iterator<std::output_iterator_tag,void,void,void,void>
{
push_iterator(Stack& stack)
: pstack(std::addressof(stack))
{}
template<class T>
auto& operator=(T&& t)
{
pstack->push(std::forward<T>(t));
return *this;
}
auto& operator*() {
return *this;
}
auto& operator++() {
return *this;
}
private:
Stack* pstack;
};
// convenience class to make a push_iterator of the correct type
template<class T, class Container>
auto stack_pusher(std::stack<T, Container>& stack)
{
return push_iterator<std::stack<T, Container>>(stack);
}
int main()
{
using namespace std;
// construct an initial vector
vector<int> init { 7,6 };
// construct a stack using a copy of the initial vector's elements
// note that the stack's storage is automatically deduced
stack<int> stack1 { { begin(init), end(init) } };
// construct a stack directly from a container initialises with an initialiser list
stack<int> stack2 { { 3,4,5 } };
// another vector
vector<int> myvector { 1, 2, 3, 4, 5, 6, 7, 8 };
// copy vector onto stack using a forward iterator
copy(begin(myvector),
end(myvector),
stack_pusher(stack1));
// copy vector onto stack using a reverse iterator
copy(rbegin(myvector),
rend(myvector),
stack_pusher(stack2));
// display the stacks
while (stack1.size() or stack2.size())
{
// function to encode an optional T as a string
auto encode = [](const auto& opt)
{
return opt ? std::to_string(opt.value()) : std::string("*");
};
// function to pop a value from a stack if it's not empty.
// return an optional
auto maybe_pop = [](auto& stack)
{
using element_type = std::decay_t<decltype(stack.top())>;
boost::optional<element_type> result;
if (stack.size()) {
result = stack.top();
stack.pop();
}
return result;
};
cout
<< encode(maybe_pop(stack1))
<< "\t"
<< encode(maybe_pop(stack2)) << endl;
}
return 0;
}
sao chép sẽ xảy ra ở đây? –
@HumamHelfawi: Có. Tôi cho rằng OP muốn điều đó, vì cô ấy nói "Tôi cần phải sao chép". Bạn cũng có thể di chuyển vectơ vào nếu bạn không cần bản gốc nữa. –
di chuyển ngữ nghĩa có thể đi vào hình ảnh ở đây ?? – basav