From 9445a97ec004ab3c77475d341d35df33e000786a Mon Sep 17 00:00:00 2001 From: Asia_Alp Date: Tue, 19 Nov 2024 19:43:53 +0300 Subject: [PATCH 1/6] Added a stack.cpp instead of stack.c with stack implementation, edited header file stack.h: added stack class with methods. --- 05_hw/stack.cpp | 101 ++++++++++++++++++++++++++++++++++++++++++++++++ 05_hw/stack.h | 53 ++++++++++--------------- 2 files changed, 122 insertions(+), 32 deletions(-) create mode 100644 05_hw/stack.cpp diff --git a/05_hw/stack.cpp b/05_hw/stack.cpp new file mode 100644 index 0000000..b1da4e0 --- /dev/null +++ b/05_hw/stack.cpp @@ -0,0 +1,101 @@ +#include +#include "stack.h" + +void Stack::initStack() +{ + this->top = nullptr; +} +void Stack::destroyStack() +{ + Node *current = this->top; + while (current != nullptr) + { + Node *tmp = current; + current = current->next; + delete tmp; + } +} + +Stack::Stack(){ + initStack(); +} +Stack::~Stack(){ + destroyStack(); +} + +Node *Stack::createNode(int data) +{ + Node *newNode = new Node(); + newNode->data = data; + newNode->next = nullptr; + return newNode; +} + +bool Stack::isEmpty() +{ + return this->top == nullptr; +} + +void Stack::push(int data) +{ + Node *newNode = createNode(data); + newNode->next = this->top; + this->top = newNode; +} + +void Stack::pop() +{ + if (isEmpty()) return; + Node *temp = this->top; + this->top = this->top->next; + delete temp; +} + +Node *Stack::searchByValue(int value) +{ + Node *current = this->top; + while (current != nullptr) + { + if (current->data == value) + { + return current; + } + current = current->next; + } + return nullptr; +} + +Node *Stack::searchByIndex(int index) +{ + Node *current = this->top; + for (int i = 0; current != nullptr; i++) + { + if (i == index) + { + return current; + } + current = current->next; + } + return nullptr; +} + +Node *Stack::getTop() +{ + return this->top; +} + +void Stack::traverseStack() +{ + if (isEmpty()) + { + std::cout << "Stack is empty! Please, add value to stack :( " << std::endl; + return; + } + Node *current = this->top; + std::cout << "Elements: "; + while (current != nullptr) + { + std::cout << " [" << current->data << "] "; + current = current->next; + } +} diff --git a/05_hw/stack.h b/05_hw/stack.h index ef0734e..940215f 100644 --- a/05_hw/stack.h +++ b/05_hw/stack.h @@ -1,40 +1,29 @@ #pragma once -#include +#ifndef STACK_H +#define STACK_H typedef struct Node { int data; - struct Node* next; + struct Node *next; } Node; -typedef struct Stack { - Node* top; -} Stack; - -#ifdef __cplusplus -extern "C" { -#endif - -Node* createNode(int data); - -void initStack(Stack* stack); - -void destroyStack(Stack *stack); - -void push(Stack* stack, int data); - -void pop(Stack* stack); - -Node* searchByValue(Stack* stack, int value); - -Node* searchByIndex(Stack* stack, int index); - -Node* getTop(Stack* stack); - -void traverseStack(Stack* stack); - -bool isEmpty(Stack* stack); - -#ifdef __cplusplus -} +//The Stack class stores data about the stack, as well as methods for working with the stack. +class Stack{ + private: + Node* top; + Node* createNode(int data); + void initStack(); + void destroyStack(); + public: + void push(int data); + void pop(); + Node *searchByValue(int value); + Node *searchByIndex(int index); + Node *getTop(); + void traverseStack(); + bool isEmpty(); + Stack(); + ~Stack(); +}; #endif From b57cf07aeaab4d5185b5e69bf11da0b84cd2c29c Mon Sep 17 00:00:00 2001 From: Asia_Alp Date: Tue, 19 Nov 2024 20:17:13 +0300 Subject: [PATCH 2/6] Deleted stack.c and main.c files, added main.cpp file stack methods: push, pop, search by value and index, get top. --- 05_hw/main.c | 36 ----------------------- 05_hw/main.cpp | 50 +++++++++++++++++++++++++++++++ 05_hw/stack.c | 78 ------------------------------------------------- 05_hw/stack.cpp | 1 + 4 files changed, 51 insertions(+), 114 deletions(-) delete mode 100644 05_hw/main.c create mode 100644 05_hw/main.cpp delete mode 100644 05_hw/stack.c diff --git a/05_hw/main.c b/05_hw/main.c deleted file mode 100644 index fded814..0000000 --- a/05_hw/main.c +++ /dev/null @@ -1,36 +0,0 @@ -#include "stack.h" - -#include - -int main() { - Stack stack; - initStack(&stack); - - push(&stack, 10); - push(&stack, 20); - push(&stack, 30); - - printf("After pushing elements:\n"); - traverseStack(&stack); - - pop(&stack); - - printf("After popping an element:\n"); - traverseStack(&stack); - - Node* searchResult = searchByValue(&stack, 20); - if (searchResult != NULL) { - printf("Element with value 20 found.\n"); - } else { - printf("Element with value 20 not found.\n"); - } - - Node* topElement = getTop(&stack); - if (topElement != NULL) { - printf("Top element: %d\n", topElement->data); - } - - return 0; -} - - diff --git a/05_hw/main.cpp b/05_hw/main.cpp new file mode 100644 index 0000000..6d09d3c --- /dev/null +++ b/05_hw/main.cpp @@ -0,0 +1,50 @@ +#include + +#include "stack.h" + +int main() { + Stack *stack = new Stack(); + int index = 0; + + stack->push(10); + stack->push(20); + stack->push(30); + std::cout << "After pushing elements:" << std::endl; + stack->traverseStack(); + + stack->pop(); + std::cout << "After popping element:" << std::endl; + stack->traverseStack(); + + Node* searchResult = stack->searchByValue(20); + if (searchResult != nullptr) { + std::cout << "Element with value 20 found." << std::endl; + } else { + std::cout << "Element with value 20 not found." << std::endl; + } + + Node* searchResult2 = stack->searchByValue(50); + if (searchResult2 != nullptr) { + std::cout << "Element with value 50 found." << std::endl; + } else { + std::cout << "Element with value 50 not found." << std::endl; + } + + std::cin >> "Enter the index to search for ..." >> index >> std::endl; + Node* searchIndex = stack->searchByIndex(index); + if (searchIndex != nullptr) { + std::cout << "Element with index " << index << " found. The value is: " << searchIndex->data << std::endl; + } else { + std::cout << "Element with index " << index << " not found." << std::endl; + } + + Node* topElement = stack->getTop(); + if (topElement != nullptr) { + std::cout << "Top element: " << topElement->data << std::endl; + } + + + + delete stack; + return 0; +} \ No newline at end of file diff --git a/05_hw/stack.c b/05_hw/stack.c deleted file mode 100644 index 0964440..0000000 --- a/05_hw/stack.c +++ /dev/null @@ -1,78 +0,0 @@ -#include -#include - -#include "stack.h" - -Node* createNode(int data) { - Node* newNode = (Node*)malloc(sizeof(Node)); - newNode->data = data; - newNode->next = NULL; - return newNode; -} - -void initStack(Stack* stack) { - stack->top = NULL; -} - -void destroyStack(Stack* stack) { - Node* current = stack->top; - while (current != NULL) { - Node *tmp = current; - current = current->next; - free(tmp); - } -} - -void push(Stack* stack, int data) { - Node* newNode = createNode(data); - newNode->next = stack->top; - stack->top = newNode; -} - -void pop(Stack* stack) { - Node* temp = stack->top; - stack->top = stack->top->next; -} - -Node* searchByValue(Stack* stack, int value) { - Node* current = stack->top; - while (current != NULL) { - if (current->data == value) { - return current; - } - } - return NULL; -} - -Node* searchByIndex(Stack* stack, int index) { - Node* current = stack->top; - int count = 0; - while (current != NULL) { - if (count == index) { - return current; - } - count++; - current = current->next; - } - return NULL; -} - -Node* getTop(Stack* stack) { - return stack->top; -} - -void traverseStack(Stack* stack) { - Node* current = stack->top; - printf("Stack elements: "); - while (current != NULL) { - printf("%d ", current->data); - current = current->next; - } - printf("\n"); -} - -bool isEmpty(Stack* stack) { - free(stack->top); - return stack->top == NULL; -} - diff --git a/05_hw/stack.cpp b/05_hw/stack.cpp index b1da4e0..a6ca3c6 100644 --- a/05_hw/stack.cpp +++ b/05_hw/stack.cpp @@ -67,6 +67,7 @@ Node *Stack::searchByValue(int value) Node *Stack::searchByIndex(int index) { + if (index < 0){return nullptr;} Node *current = this->top; for (int i = 0; current != nullptr; i++) { From 6b7d27e8d6ff206393e162c65219f6e071d3cd3e Mon Sep 17 00:00:00 2001 From: Asia_Alp Date: Wed, 20 Nov 2024 19:02:15 +0300 Subject: [PATCH 3/6] Added gtest for verification. --- 05_hw/test_suite_stack.cpp | 124 +++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 05_hw/test_suite_stack.cpp diff --git a/05_hw/test_suite_stack.cpp b/05_hw/test_suite_stack.cpp new file mode 100644 index 0000000..33a64de --- /dev/null +++ b/05_hw/test_suite_stack.cpp @@ -0,0 +1,124 @@ +#include +#include "stack.h" + +class StackTest : public ::testing::Test { +protected: + void SetUp() override { + stack = new Stack(); + } + + void TearDown() override { + delete stack; + } + + Stack* stack; +}; + +TEST_F(StackTest, IsEmptySuccess) { + EXPECT_EQ(stack->isEmpty(),true); +} + +TEST_F(StackTest, IsEmptyFail) { + stack->push(100); + EXPECT_EQ(stack->isEmpty(),false); +} + +TEST_F(StackTest, GetTopEmpty) { + Node *result = stack->getTop(); + EXPECT_EQ(result, nullptr); +} + +TEST_F(StackTest, Push) { + stack->push(1); + Node *result = stack->getTop(); + EXPECT_EQ(result->data,1); +} + +TEST_F(StackTest, Pop) { + stack->push(2); + stack->pop(); + EXPECT_EQ(stack->isEmpty(),true); +} + +TEST_F(StackTest, PopFromEmptyStack) { + stack->pop(); + EXPECT_EQ(stack->isEmpty(),true); +} + +TEST_F(StackTest, GetTop) { + stack->push(100); + stack->push(75); + stack->push(50); + stack->push(25); + stack->pop(); + Node *result = stack->getTop(); + EXPECT_EQ(result->data,100); +} + +TEST_F(StackTest, SearchByValueSuccess) { + stack->push(100); + stack->push(75); + stack->push(50); + stack->push(25); + Node *result = stack->searchByValue(25); + EXPECT_EQ(result->data,25); +} + +TEST_F(StackTest, SearchByValueFail) { + stack->push(100); + stack->push(75); + stack->push(50); + stack->push(25); + Node *result = stack->searchByValue(10); + EXPECT_EQ(result,nullptr); +} + +TEST_F(StackTest, SearchByIndexSuccess) { + stack->push(100); + stack->push(75); + stack->push(50); + stack->push(25); + Node * result = stack->searchByIndex(0); + EXPECT_EQ(result->data,100); +} + +TEST_F(StackTest, SearchByIndexFail1) { + stack->push(100); + stack->push(75); + stack->push(50); + stack->push(25); + Node *result = stack->searchByIndex(5); + EXPECT_EQ(result,nullptr); +} + +TEST_F(StackTest, SearchByIndexFail2) { + stack->push(100); + stack->push(75); + stack->push(50); + stack->push(25); + Node *result = stack->searchByIndex(-1); + EXPECT_EQ(result,nullptr); +} + +TEST_F(StackTest, TraverseStack) { + testing::internal::CaptureStdout(); + stack->push(100); + stack->push(75); + stack->push(50); + stack->push(25); + stack->traverseStack(); + std::string captured_stdout = testing::internal::GetCapturedStdout(); + EXPECT_EQ("Elements: [100] [75] [50] [25] \n", captured_stdout); +} + +TEST_F(StackTest, TraverseStackEmpty) { + testing::internal::CaptureStdout(); + stack->traverseStack(); + std::string captured_stdout = testing::internal::GetCapturedStdout(); + EXPECT_EQ("Stack is empty! Please, add value to stack :( \n", captured_stdout); +} + +int main(int argc, char **argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} \ No newline at end of file From 815cae2a7659ff470ad18aeeb0f8e721c2243d74 Mon Sep 17 00:00:00 2001 From: Asia_Alp Date: Wed, 20 Nov 2024 19:12:34 +0300 Subject: [PATCH 4/6] Get dependencies into CMAkeList. --- 05_hw/CMakeLists.txt | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/05_hw/CMakeLists.txt b/05_hw/CMakeLists.txt index 6f5e398..e9ddc12 100644 --- a/05_hw/CMakeLists.txt +++ b/05_hw/CMakeLists.txt @@ -1,7 +1,10 @@ cmake_minimum_required(VERSION 3.10) project(stack) +find_package(GTest REQUIRED) -add_library(stack stack.c) - -add_executable(main main.c) +add_library(stack stack.cpp) +add_executable(main main.cpp) target_link_libraries(main stack) + +add_executable(test_suite_stack test_suite_stack.cpp) +target_link_libraries(test_suite_stack stack GTest::GTest) From 11c6a603871fc38b0f447e2380be0a9f7294fd45 Mon Sep 17 00:00:00 2001 From: Asia_Alp Date: Wed, 20 Nov 2024 19:25:36 +0300 Subject: [PATCH 5/6] Added CMake compilation flags into CMakeList. --- 05_hw/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/05_hw/CMakeLists.txt b/05_hw/CMakeLists.txt index e9ddc12..ab0e97f 100644 --- a/05_hw/CMakeLists.txt +++ b/05_hw/CMakeLists.txt @@ -2,6 +2,8 @@ cmake_minimum_required(VERSION 3.10) project(stack) find_package(GTest REQUIRED) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer -O3") + add_library(stack stack.cpp) add_executable(main main.cpp) target_link_libraries(main stack) From 7ec93559d71d1409eac3ed60a381231df1266d5d Mon Sep 17 00:00:00 2001 From: Asia_Alp Date: Thu, 21 Nov 2024 19:52:21 +0300 Subject: [PATCH 6/6] Added bench for push and pop functions, added packages in MakeList. --- 05_hw/CMakeLists.txt | 6 +++++- 05_hw/benchmarks.cpp | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 05_hw/benchmarks.cpp diff --git a/05_hw/CMakeLists.txt b/05_hw/CMakeLists.txt index ab0e97f..b549dba 100644 --- a/05_hw/CMakeLists.txt +++ b/05_hw/CMakeLists.txt @@ -1,6 +1,7 @@ -cmake_minimum_required(VERSION 3.10) +cmake_minimum_required(VERSION 3.17) project(stack) find_package(GTest REQUIRED) +find_package(benchmark REQUIRED) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer -O3") @@ -10,3 +11,6 @@ target_link_libraries(main stack) add_executable(test_suite_stack test_suite_stack.cpp) target_link_libraries(test_suite_stack stack GTest::GTest) + +add_executable(benchmark benchmark.cpp) +target_link_libraries(benchmark stack benchmark::benchmark) diff --git a/05_hw/benchmarks.cpp b/05_hw/benchmarks.cpp new file mode 100644 index 0000000..bacbd96 --- /dev/null +++ b/05_hw/benchmarks.cpp @@ -0,0 +1,41 @@ +#include +#include "stack.h" + +//Stress functions pop and push of class Stack by using Google Bench lib +// See more functions in user guide for lib at github https://github.com/google/benchmark/blob/main/docs/user_guide.md + +class StackBench : public benchmark::Fixture { +public: + void SetUp(::benchmark::State& state) { + stack = new Stack(); + } + + void TearDown(::benchmark::State& state) { + delete stack; + } + Stack* stack; +}; + + +BENCHMARK_DEFINE_F(StackBench, PushTest)(benchmark::State& st) { + for (auto _ : st) { + for(int i=0; i < st.range(0); i++){ + stack->push(i); + } + } +} + +BENCHMARK_DEFINE_F(StackBench, PopTest)(benchmark::State& st) { + for(int i=0; i < st.range(0); i++){ + stack->push(i); + } + for (auto _ : st) { + for(int i=0; i < st.range(0); i++){ + stack->pop(); + } + } +} +BENCHMARK_REGISTER_F(StackBench, PushTest)->Arg(100000)->Arg(200000)->Arg(400000)->Arg(80000)->Arg(1600000)->Arg(3200000)->MeasureProcessCPUTime(); +BENCHMARK_REGISTER_F(StackBench, PopTest)->Arg(100000)->Arg(200000)->Arg(400000)->Arg(80000)->Arg(1600000)->Arg(3200000)->MeasureProcessCPUTime(); + +BENCHMARK_MAIN(); \ No newline at end of file