diff --git a/CMakeLists.txt b/CMakeLists.txt index cccefe5..c86a8b1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -134,6 +134,9 @@ set(APP_SOURCES "src/core/datatypes/container/unordered/UnorderedMap.cpp" "src/core/expression/Lambda.cpp" "src/core/expression/FunctionPointer.cpp" + "src/core/datatypes/container/adapter/Queue.cpp" + "src/core/datatypes/container/adapter/Stack.cpp" + "src/core/datatypes/container/sequence/Deque.cpp" ## LC "src/leetcode/arrays/two_sum/TwoSum.cpp" "src/leetcode/arrays/median_two_arrays/MedianTwoSortedArrays.cpp" diff --git a/src/core/basics/ControlFlow.cpp b/src/core/basics/ControlFlow.cpp index 6b4913a..8e67935 100644 --- a/src/core/basics/ControlFlow.cpp +++ b/src/core/basics/ControlFlow.cpp @@ -82,7 +82,7 @@ void loops() { ++j; } while (j < 2); - // for + // for(initialization; condition; update) for (int k = 0; k < 3; ++k) { cout << "for loop k = " << k << "\n"; } diff --git a/src/core/datatypes/container/README.md b/src/core/datatypes/container/README.md index 414bc8e..644c4e7 100644 --- a/src/core/datatypes/container/README.md +++ b/src/core/datatypes/container/README.md @@ -19,4 +19,11 @@ Unordered associative containers implement unsorted (hashed) data structures tha |unordered_map|collection of key-value pairs, hashed by keys, keys are unique| |unordered_set|collection of unique keys, hashed by keys| +## 3. Adapter Container +**Container adaptors** provide a different interface for **sequential containers**. +|name|description| +|---|---| +|queue|apdapts a container to provide queue (**FIFO** data structure)| +|stack|adapts a container to provide stack (**LIFO** data structure)| + TBD \ No newline at end of file diff --git a/src/core/datatypes/container/adapter/Queue.cpp b/src/core/datatypes/container/adapter/Queue.cpp new file mode 100644 index 0000000..9b97966 --- /dev/null +++ b/src/core/datatypes/container/adapter/Queue.cpp @@ -0,0 +1,52 @@ +// cppcheck-suppress-file [] + +/** + * std::queue + * template< + * class T, + * class Container = std::deque + * > class queue; + * + * Queue acts as a wrapper to the underlying container (sequence container e.g. std::deque, std::list) + * but only a specific + * set of functions is provided. + * It pushs the elements on the back of the underlying container and pops them from the front + * + */ +#include +#include // for std::queue + +namespace { +void run() { + // 1. Init + std::queue m_queue{}; + + // 2. Modifiers + m_queue.push(0); // inserts elements at the end + m_queue.push(1); // q = 0 1 + m_queue.push(2); // q = 0 1 2 + m_queue.push(3); // q = 0 1 2 3 + + m_queue.pop(); // removes the 1st element q = 1 2 3 + + // 3. Element access + std::cout << "fisrt ele: " << m_queue.front() << "\n"; + std::cout << "last ele: " << m_queue.back() << "\n"; + + // 4. Get all elements and remove + std::cout << "all ele: \n"; + for (; !m_queue.empty(); m_queue.pop()) { + std::cout << m_queue.front() << " "; + } + std::cout << "\n"; +} +} // namespace + +struct QueueRunner { + QueueRunner() { + std::cout << "\n--- std::queue Example ---\n"; + run(); + } +}; + +static QueueRunner autoRunner; \ No newline at end of file diff --git a/src/core/datatypes/container/adapter/Stack.cpp b/src/core/datatypes/container/adapter/Stack.cpp new file mode 100644 index 0000000..ea254fc --- /dev/null +++ b/src/core/datatypes/container/adapter/Stack.cpp @@ -0,0 +1,51 @@ +// cppcheck-suppress-file [] + +/** + * std::stack + * template< + * class T, + * class Container = std::deque + * > class stack; + * + * Queue acts as a wrapper to the underlying container (sequence container e.g. std::deque, std::list) + * but only a specific + * set of functions is provided. + * It pushs and pops the element from the back of the underlying container, a.k.a the top of the stack + * + */ +#include +#include // for std::queue + +namespace { +void run() { + // 1. Init + std::stack m_stack{}; + + // 2. Modifiers + m_stack.push(0); // inserts elements at the end + m_stack.push(1); // q = 0 1 + m_stack.push(2); // q = 0 1 2 + m_stack.push(3); // q = 0 1 2 3 + m_stack.pop(); // removes the top element q = 0 1 2 + + // 3. Element access + std::cout << "top ele: " << m_stack.top() + << "\n"; // access the top of the stack + + // 4. Get all elements and remove + std::cout << "all ele (reverse): \n"; + for (; !m_stack.empty(); m_stack.pop()) { + std::cout << m_stack.top() << " "; + } + std::cout << "\n"; +} +} // namespace + +struct StackRunner { + StackRunner() { + std::cout << "\n--- std::stack Example ---\n"; + run(); + } +}; + +static StackRunner autoRunner; \ No newline at end of file diff --git a/src/core/datatypes/container/sequence/Deque.cpp b/src/core/datatypes/container/sequence/Deque.cpp new file mode 100644 index 0000000..eb4d3f1 --- /dev/null +++ b/src/core/datatypes/container/sequence/Deque.cpp @@ -0,0 +1,45 @@ +// cppcheck-suppress-file [] + +/** + * Double-ended queue is an indexed sequence container that allows fast insertion and deletion + * and never invalidates pointers or references to the rest of the elements because it use two pointer for 1 elem. +=> Indexing and iterating performance < vector + * The elements of a deque are not stored contiguously + + * Insertion or removal of elements - linear O(n) + * Random access - constant O(1) + */ +#include +#include + +namespace { +void run() { + // 1) Init + std::deque m_deque = {9, 100, 0}; + + // 2) Modifiers + m_deque.clear(); + + m_deque.push_back(1); + m_deque.push_back(2); + m_deque.push_back(3); + m_deque.push_back(4); + m_deque.pop_back(); + m_deque.pop_front(); + m_deque.push_front(99); + + for (const auto& e : m_deque) { + std::cout << e << " "; + } + std::cout << std::endl; +} +} // namespace + +struct DequeRunner { + DequeRunner() { + std::cout << "\n--- std::deque Example ---\n"; + run(); + } +}; + +static DequeRunner autoRunner; \ No newline at end of file