diff --git a/CMakeLists.txt b/CMakeLists.txt index b40c0dd11c..8939021ea1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,9 +10,5 @@ else() add_compile_options(-Wall -Wextra -Wpedantic -Wno-gnu-empty-struct -Wno-unused-parameter) endif() -add_subdirectory(LibraryC) add_subdirectory(LibraryCPP) -add_subdirectory(LibraryCPPClass) -add_subdirectory(LibraryCPPTemplate) - -add_subdirectory(Lab1C) +add_subdirectory(Lab2CPP) diff --git a/Lab2CPP/CMakeLists.txt b/Lab2CPP/CMakeLists.txt new file mode 100644 index 0000000000..ecb0eaf722 --- /dev/null +++ b/Lab2CPP/CMakeLists.txt @@ -0,0 +1,9 @@ +add_executable(Lab2CPP lab2.cpp) +target_include_directories(Lab2CPP PUBLIC ../LibraryCPP) +target_link_libraries(Lab2CPP LibraryCPP) + +add_test(NAME Test1 COMMAND Lab2CPP "1+2*3") +add_test(NAME Test2 COMMAND Lab2CPP "(1+2)*3") + +set_tests_properties(Test1 PROPERTIES PASS_REGULAR_EXPRESSION "7") +set_tests_properties(Test2 PROPERTIES PASS_REGULAR_EXPRESSION "9") diff --git a/Lab2CPP/lab2.cpp b/Lab2CPP/lab2.cpp new file mode 100644 index 0000000000..b7be72b4f2 --- /dev/null +++ b/Lab2CPP/lab2.cpp @@ -0,0 +1,124 @@ +#include +#include +#include +#include "list.h" +#include "stack.h" + +unsigned int priority(const char symbol) +{ + if (symbol == '*' || symbol == '/') + return 3; + if (symbol == '+' || symbol == '-') + return 2; + if (symbol == '(') + return 1; + + return 0; +} + +std::string RPN(std::string data) +{ + Stack* stack = stack_create(); + std::string res = ""; + for (size_t i = 0; i < data.size(); i++) + { + if (isdigit(data[i])) + { + res += data[i]; + } + else + { + if (data[i] == '(') + { + stack_push(stack, data[i]); + } + else if (data[i] == ')') + { + while (!stack_empty(stack) && stack_get(stack) != '(') + { + res += stack_get(stack); + stack_pop(stack); + } + if (!stack_empty(stack) && stack_get(stack) == '(') + { + stack_pop(stack); + } + } + else + { + while (!stack_empty(stack) && priority(stack_get(stack)) >= priority(data[i])) + { + res += stack_get(stack); + stack_pop(stack); + } + stack_push(stack, data[i]); + } + } + } + + while (!stack_empty(stack)) + { + res += stack_get(stack); + stack_pop(stack); + } + + stack_delete(stack); + return res; +} + +Data solve(std::string data) +{ + Stack* stack = stack_create(); + for (size_t i = 0; i < data.size(); i++) + { + if (isdigit(data[i])) + stack_push(stack, data[i] - '0'); + else + { + Data val1 = stack_get(stack); + stack_pop(stack); + Data val2 = stack_get(stack); + stack_pop(stack); + Data res = 0; + + switch (data[i]) + { + case '+': res = val1 + val2; + break; + case '-': res = val1 - val2; + break; + case '*': res = val1 * val2; + break; + case '/': res = val1 / val2; + break; + } + + stack_push(stack, res); + } + } + + Data res = stack_get(stack); + stack_delete(stack); + return res; +} + +std::string calculate(std::string expr) +{ + expr = RPN(expr); + expr = std::to_string(solve(expr)); + + return expr; +} + +int main(int argc, char** argv) +{ + std::string data = ""; + char* ch = argv[1]; + while (*ch != '\0') + { + data += *(ch); + ch++; + } + std::cout << calculate(data); + return 0; +} diff --git a/LibraryCPP/CMakeLists.txt b/LibraryCPP/CMakeLists.txt index dbd7769feb..607f6546ac 100644 --- a/LibraryCPP/CMakeLists.txt +++ b/LibraryCPP/CMakeLists.txt @@ -1,3 +1,3 @@ -add_library(LibraryCPP STATIC array.cpp list.cpp queue.cpp stack.cpp vector.cpp) +add_library(LibraryCPP STATIC list.cpp stack.cpp) add_subdirectory(Tests) diff --git a/LibraryCPP/Tests/CMakeLists.txt b/LibraryCPP/Tests/CMakeLists.txt index c903f9d7f3..d871c096be 100644 --- a/LibraryCPP/Tests/CMakeLists.txt +++ b/LibraryCPP/Tests/CMakeLists.txt @@ -1,12 +1,12 @@ -# add_executable(TestArrayCPP array.cpp) -# target_include_directories(TestArrayCPP PUBLIC ..) -# target_link_libraries(TestArrayCPP LibraryCPP) -# add_test(TestArrayCPP TestArrayCPP) +#add_executable(TestArrayCPP array.cpp) +#target_include_directories(TestArrayCPP PUBLIC ..) +#target_link_libraries(TestArrayCPP LibraryCPP) +#add_test(TestArrayCPP TestArrayCPP) -# add_executable(TestListCPP list.cpp) -# target_include_directories(TestListCPP PUBLIC ..) -# target_link_libraries(TestListCPP LibraryCPP) -# add_test(TestListCPP TestListCPP) +add_executable(TestListCPP list.cpp) +target_include_directories(TestListCPP PUBLIC ..) +target_link_libraries(TestListCPP LibraryCPP) +add_test(TestListCPP TestListCPP) # add_executable(TestQueueCPP queue.cpp) # target_include_directories(TestQueueCPP PUBLIC ..) @@ -14,10 +14,10 @@ # add_test(TestQueueCPP TestQueueCPP) # set_tests_properties(TestQueueCPP PROPERTIES TIMEOUT 10) -# add_executable(TestStackCPP stack.cpp) -# target_include_directories(TestStackCPP PUBLIC ..) -# target_link_libraries(TestStackCPP LibraryCPP) -# add_test(TestStackCPP TestStackCPP) +add_executable(TestStackCPP stack.cpp) +target_include_directories(TestStackCPP PUBLIC ..) +target_link_libraries(TestStackCPP LibraryCPP) +add_test(TestStackCPP TestStackCPP) # add_executable(TestVectorCPP vector.cpp) # target_include_directories(TestVectorCPP PUBLIC ..) diff --git a/LibraryCPP/array.h b/LibraryCPP/array.h index b541ebe8b4..3b61df7ef5 100644 --- a/LibraryCPP/array.h +++ b/LibraryCPP/array.h @@ -2,6 +2,8 @@ #define ARRAY_H #include +#include +#include // Non-resizeable array // Stores integer values inside @@ -10,18 +12,21 @@ typedef int Data; struct Array; // create array -Array *array_create(size_t size); +Array* array_create(size_t size); // delete array, free memory -void array_delete(Array *arr); +void array_delete(Array* arr); // returns specified array element -Data array_get(const Array *arr, size_t index); +Data array_get(const Array* arr, size_t index); // sets the specified array element to the value -void array_set(Array *arr, size_t index, Data value); +void array_set(Array* arr, size_t index, Data value); // returns array size -size_t array_size(const Array *arr); +size_t array_size(const Array* arr); + +// fill array from file +Array* fill_array(std::ifstream &in); #endif diff --git a/LibraryCPP/list.cpp b/LibraryCPP/list.cpp index a8946b5793..a36021b4cd 100644 --- a/LibraryCPP/list.cpp +++ b/LibraryCPP/list.cpp @@ -3,59 +3,130 @@ struct ListItem { + Data value; + ListItem* next = nullptr; + ListItem* prev = nullptr; }; struct List { + ListItem* node = nullptr; }; List *list_create() { - return new List; + List* newList = new List; + return newList; } -void list_delete(List *list) +void list_delete(List* list) { - // TODO: free items - delete list; + if (list != nullptr) + { + ListItem* current = list->node; + while (current != nullptr) + { + ListItem* next = current->next; + delete current; + current = next; + } + delete list; + } } + ListItem *list_first(List *list) { - return NULL; + if (list != nullptr) + return list->node; + return nullptr; } Data list_item_data(const ListItem *item) { + if (item != nullptr) + return item->value; return (Data)0; } ListItem *list_item_next(ListItem *item) { - return NULL; + if(item != nullptr) + return item->next; + return nullptr; } ListItem *list_item_prev(ListItem *item) { - return NULL; + if (item != nullptr && item->prev != nullptr) + return item->prev; + return nullptr; } -ListItem *list_insert(List *list, Data data) +ListItem* list_insert(List* list, Data data) { - return NULL; + ListItem* newEl = new ListItem; + newEl->value = data; + newEl->prev = nullptr; + + if (list->node != nullptr) + { + newEl->next = list->node; + list->node->prev = newEl; + } + else + newEl->next = nullptr; + + list->node = newEl; + + return newEl; } -ListItem *list_insert_after(List *list, ListItem *item, Data data) +ListItem* list_insert_after(List* list, ListItem* item, Data data) { - return NULL; + if (list != nullptr && item != nullptr) + { + ListItem* newEl = new ListItem; + + newEl->prev = item; + newEl ->next = item->next; + newEl->value = data; + + if (item->next != nullptr) + item->next->prev = newEl; + item->next = newEl; + + return newEl; + } + return nullptr; } ListItem *list_erase_first(List *list) { + if (list != nullptr && list->node != nullptr) + { + ListItem* temp = list->node->next; + if(temp != nullptr) + temp->prev = nullptr; + delete list->node; + list->node = temp; + + return list->node; + } return NULL; } ListItem *list_erase_next(List *list, ListItem *item) { - return NULL; + if (list != nullptr && item != nullptr && item->next != nullptr) + { + if(item->next->next != nullptr) + item->next->next->prev = item; + ListItem* temp = item->next->next; + delete item->next; + item->next = temp; + return temp; + } + + return nullptr; } diff --git a/LibraryCPP/stack.cpp b/LibraryCPP/stack.cpp index c090abba1c..5101c783ef 100644 --- a/LibraryCPP/stack.cpp +++ b/LibraryCPP/stack.cpp @@ -1,34 +1,52 @@ #include "stack.h" +#include "list.h" struct Stack { + List* list = nullptr; }; Stack *stack_create() { - return new Stack; + Stack* stack = new Stack; + stack->list = list_create(); + + return stack; } void stack_delete(Stack *stack) { - // TODO: free stack elements + if(stack != nullptr) + list_delete(stack->list); delete stack; } void stack_push(Stack *stack, Data data) { + if(stack != nullptr) + list_insert(stack->list, data); } Data stack_get(const Stack *stack) { + if(stack != nullptr) + return list_item_data(list_first(stack->list)); return (Data)0; } void stack_pop(Stack *stack) { + if(stack != nullptr) + list_erase_first(stack->list); } bool stack_empty(const Stack *stack) { + if (stack != nullptr) + { + if (list_first(stack->list) == nullptr) + return true; + return false; + } return true; } diff --git "a/\320\234\320\270\321\205\320\260\320\271\320\273\320\276\320\262 \320\240\320\276\320\274\320\260\320\275 3091" "b/\320\234\320\270\321\205\320\260\320\271\320\273\320\276\320\262 \320\240\320\276\320\274\320\260\320\275 3091" new file mode 100644 index 0000000000..42089a4ec4 --- /dev/null +++ "b/\320\234\320\270\321\205\320\260\320\271\320\273\320\276\320\262 \320\240\320\276\320\274\320\260\320\275 3091" @@ -0,0 +1 @@ +Михайлов Роман 3091