diff --git a/CMakeLists.txt b/CMakeLists.txt index b40c0dd11c..ffd1152be4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,9 +10,13 @@ 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(LibraryC) +#add_subdirectory(LibraryCPP) +#add_subdirectory(LibraryCPPClass) add_subdirectory(LibraryCPPTemplate) -add_subdirectory(Lab1C) +#add_subdirectory(Lab1C) +#add_subdirectory(Lab1CPP) +#add_subdirectory(Lab2CPP) +#add_subdirectory(Lab3CPP) +add_subdirectory(Lab4CPPTemplate) diff --git a/Lab1C/CMakeLists.txt b/Lab1C/CMakeLists.txt index f4da4d8372..f32851ad11 100644 --- a/Lab1C/CMakeLists.txt +++ b/Lab1C/CMakeLists.txt @@ -2,5 +2,5 @@ add_executable(Lab1C lab1.c) target_include_directories(Lab1C PUBLIC ../LibraryC) target_link_libraries(Lab1C LibraryC) -add_test(NAME TestLab1C COMMAND Lab1C ${CMAKE_CURRENT_SOURCE_DIR}/input.txt) -set_property(TEST TestLab1C PROPERTY PASS_REGULAR_EXPRESSION "1 2 3 4 5") +#add_test(NAME TestLab1C COMMAND Lab1C ${CMAKE_CURRENT_SOURCE_DIR}/input.txt) +#set_property(TEST TestLab1C PROPERTY PASS_REGULAR_EXPRESSION "1 2 3 4 5") diff --git a/Lab1CPP/CMakeLists.txt b/Lab1CPP/CMakeLists.txt new file mode 100644 index 0000000000..4b50a7a26c --- /dev/null +++ b/Lab1CPP/CMakeLists.txt @@ -0,0 +1,8 @@ +add_executable(Lab1CPP lab1.cpp) +target_include_directories(Lab1CPP PUBLIC ../LibraryCPP) +target_link_libraries(Lab1CPP LibraryCPP) + +add_test(NAME TestLab1CPP COMMAND $ ${CMAKE_CURRENT_SOURCE_DIR}/input.txt) +set_property(TEST TestLab1CPP PROPERTY PASS_REGULAR_EXPRESSION "2 3 5 7 11.*5 6 7 8 9") + + diff --git a/Lab1CPP/input.txt b/Lab1CPP/input.txt new file mode 100644 index 0000000000..e79d2ce3ce --- /dev/null +++ b/Lab1CPP/input.txt @@ -0,0 +1,4 @@ +10 +10 +1 2 3 4 5 6 7 8 9 0 + diff --git a/Lab1CPP/lab1.cpp b/Lab1CPP/lab1.cpp new file mode 100644 index 0000000000..dc1e9c8e75 --- /dev/null +++ b/Lab1CPP/lab1.cpp @@ -0,0 +1,122 @@ +#include +#include +#include "array.h" + +Array *array_create_and_read(std::istream& input) +{ + size_t n; + input >> n; + + /* Create array */ + Array *arr = array_create(n); + /* Read array data */ + for (size_t i = 0 ; i < n ; ++i) + { + Data x; + input >> x; + array_set(arr, i, x); + } + return arr; +} + +Array* array_create_read_size(std::istream& input) +{ + size_t n; + input >> n; + return array_create(n); +} + + +bool is_prime(int n) +{ + if (n < 2) return false; + for (int i = 2; i * i <= n; ++i) + if (n % i == 0) + return false; + return true; +} + +/*Read an integer from a file, create an array of this size. +Fill the array with prime numbers, starting with 2. Display the array on the screen.*/ +void task1(Array *arr) +{ + array_set(arr, 0, 2); + int num = 3; + for (size_t i = 1; i < array_size(arr); ++num) + { + if (is_prime(num)) + { + array_set(arr, i, num); + ++i; + } + + } + + + for (size_t i = 0; i < array_size(arr); ++i) + { + std::cout << array_get(arr, i) << " "; + } + std::cout << "\n"; + +} + +/*Read an integer from a file, create an array of this size and +fill it with numbers from the file. Find five neighboring elements, +the sum of whose values is maximum. Display the result on the screen.*/ +void task2(Array *arr) +{ + size_t n = array_size(arr); + if (n < 5) + { + return; + } + + int maxSum = 0; + int currSum = 0; + size_t indx = 0; + + for (size_t i = 0; i < 5; ++i) + currSum += array_get(arr, i); + maxSum = currSum; + + for (size_t i = 5; i < n; ++i) + { + currSum = currSum - array_get(arr, i - 5) + array_get(arr, i); + if (currSum > maxSum) + { + maxSum = currSum; + indx = i - 4; + } + } + + for (size_t i = indx; i < indx + 5; ++i) + { + std::cout << array_get(arr, i) << " "; + } + std::cout << "\n"; +} + +int main(int argc, char **argv) +{ + if (argc < 2) + { + return 1; + } + + std::ifstream input(argv[1]); + if (!input) + { + return 1; + } + + Array* arr = array_create_read_size(input); + task1(arr); + array_delete(arr); + + arr = array_create_and_read(input); + task2(arr); + array_delete(arr); + + return 0; +} diff --git a/Lab2CPP/CMakeLists.txt b/Lab2CPP/CMakeLists.txt new file mode 100644 index 0000000000..64313094bf --- /dev/null +++ b/Lab2CPP/CMakeLists.txt @@ -0,0 +1,18 @@ +add_executable(Lab2CPP lab2.cpp) +target_include_directories(Lab2CPP PUBLIC ../LibraryCPP) +target_link_libraries(Lab2CPP LibraryCPP) + +add_test(NAME TestLab2CPP COMMAND $ ${CMAKE_CURRENT_SOURCE_DIR}/input.txt ${CMAKE_CURRENT_SOURCE_DIR}/inputnum.txt) +set_property(TEST TestLab2CPP PROPERTY PASS_REGULAR_EXPRESSION "72 101 108") + +add_test(NAME TestLab2CPP2 COMMAND $ ${CMAKE_CURRENT_SOURCE_DIR}/input2.txt ${CMAKE_CURRENT_SOURCE_DIR}/inputnum.txt) +set_property(TEST TestLab2CPP2 PROPERTY PASS_REGULAR_EXPRESSION "5 10") + +add_test(NAME TestLab2CPP3 COMMAND $ ${CMAKE_CURRENT_SOURCE_DIR}/input3.txt ${CMAKE_CURRENT_SOURCE_DIR}/inputnum.txt) +set_property(TEST TestLab2CPP3 PROPERTY PASS_REGULAR_EXPRESSION "0") + +add_test(NAME TestLab2CPP4 COMMAND $ ${CMAKE_CURRENT_SOURCE_DIR}/input4.txt ${CMAKE_CURRENT_SOURCE_DIR}/inputnum.txt) +set_property(TEST TestLab2CPP4 PROPERTY PASS_REGULAR_EXPRESSION "10") + +add_test(NAME TestLab2CPP5 COMMAND $ ${CMAKE_CURRENT_SOURCE_DIR}/input5.txt ${CMAKE_CURRENT_SOURCE_DIR}/inputnum.txt) +set_property(TEST TestLab2CPP5 PROPERTY PASS_REGULAR_EXPRESSION "10 20") \ No newline at end of file diff --git a/Lab2CPP/input.txt b/Lab2CPP/input.txt new file mode 100644 index 0000000000..9cab2b69c5 --- /dev/null +++ b/Lab2CPP/input.txt @@ -0,0 +1,2 @@ +10 33 100 108 114 119 32 44 111 108 101 72 peek setr peek setr peek peek setr peek setr peek setr peek setr peek setr peek setr peek setr peek setr peek setr peek setr + diff --git a/Lab2CPP/input2.txt b/Lab2CPP/input2.txt new file mode 100644 index 0000000000..5ef23ccd7c --- /dev/null +++ b/Lab2CPP/input2.txt @@ -0,0 +1,3 @@ +2 3 add peek sub peek mul peek div peek sqrt peek sq peek get peek cond end setr repeat peek + + diff --git a/Lab2CPP/input3.txt b/Lab2CPP/input3.txt new file mode 100644 index 0000000000..eddde0050f --- /dev/null +++ b/Lab2CPP/input3.txt @@ -0,0 +1,2 @@ +0 0 div peek + diff --git a/Lab2CPP/input4.txt b/Lab2CPP/input4.txt new file mode 100644 index 0000000000..60b4bf67ec --- /dev/null +++ b/Lab2CPP/input4.txt @@ -0,0 +1 @@ +get peek diff --git a/Lab2CPP/input5.txt b/Lab2CPP/input5.txt new file mode 100644 index 0000000000..3cd31a8019 --- /dev/null +++ b/Lab2CPP/input5.txt @@ -0,0 +1 @@ +10 peek 20 peek diff --git a/Lab2CPP/inputnum.txt b/Lab2CPP/inputnum.txt new file mode 100644 index 0000000000..021ea30c0e --- /dev/null +++ b/Lab2CPP/inputnum.txt @@ -0,0 +1,2 @@ +10 + diff --git a/Lab2CPP/lab2.cpp b/Lab2CPP/lab2.cpp new file mode 100644 index 0000000000..5552a3092c --- /dev/null +++ b/Lab2CPP/lab2.cpp @@ -0,0 +1,250 @@ +#include +#include +#include +#include +#include +#include "stack.h" + +enum Command { + cmd_none = 0, + cmd_add = 1, + cmd_sub = 2, + cmd_mul = 3, + cmd_div = 4, + cmd_sqrt = 5, + cmd_sq = 6, + cmd_get = 7, + cmd_peek = 8, + cmd_cond = 9, + cmd_end = 10, + cmd_setr = 11, + cmd_repeat = 12, + cmd_push = 13 +}; + +struct CommandItem { + Command cmd; + int value; +}; + +Command command_to_num(const std::string& cmd) { + if (cmd == "add") return cmd_add; + if (cmd == "sub") return cmd_sub; + if (cmd == "mul") return cmd_mul; + if (cmd == "div") return cmd_div; + if (cmd == "sqrt") return cmd_sqrt; + if (cmd == "sq") return cmd_sq; + if (cmd == "get") return cmd_get; + if (cmd == "peek") return cmd_peek; + if (cmd == "cond") return cmd_cond; + if (cmd == "end") return cmd_end; + if (cmd == "setr") return cmd_setr; + if (cmd == "repeat") return cmd_repeat; + return cmd_none; +} + +void read_numbers_and_commands_from_file(const char* filename, std::vector& cmds) { + std::ifstream file(filename); + std::string token; + + while (file >> token) { + Command cmd_code = command_to_num(token); + if (cmd_code != cmd_none) { + cmds.push_back({ cmd_code, 0 }); + } + else { + int num = std::stoi(token); + cmds.push_back({ cmd_push, num }); + } + } +} + +size_t skip_cond_block(const std::vector& cmds, size_t current_index, size_t count) { + size_t nested = 0; + size_t i = current_index + 1; + while (i < count) { + if (cmds[i].cmd == cmd_cond) nested++; + else if (cmds[i].cmd == cmd_end) { + if (nested == 0) break; + nested--; + } + i++; + } + return i + 1; +} + +void execute_commands(const std::vector& cmds, Stack* nums, std::ifstream& inputnum) { + int loop_var = 0; + size_t i = 0; + size_t count = cmds.size(); + + while (i < count) { + CommandItem cmdItem = cmds[i]; + switch (cmdItem.cmd) { + + case cmd_push: + stack_push(nums, cmdItem.value); + ++i; + break; + + case cmd_peek: + if (!stack_empty(nums)) { + Data val = stack_get(nums); + std::cout << val << " "; + } + ++i; + break; + + case cmd_setr: + if (!stack_empty(nums)) { + loop_var = stack_get(nums); + stack_pop(nums); + } + ++i; + break; + + case cmd_add: + if (!stack_empty(nums)) { + int a = stack_get(nums); stack_pop(nums); + if (!stack_empty(nums)) { + int b = stack_get(nums); stack_pop(nums); + stack_push(nums, a + b); + } + } + ++i; + break; + + case cmd_sub: + if (!stack_empty(nums)) { + int a = stack_get(nums); stack_pop(nums); + if (!stack_empty(nums)) { + int b = stack_get(nums); stack_pop(nums); + stack_push(nums, b - a); + } + } + ++i; + break; + + case cmd_mul: + if (!stack_empty(nums)) { + int a = stack_get(nums); stack_pop(nums); + if (!stack_empty(nums)) { + int b = stack_get(nums); stack_pop(nums); + stack_push(nums, a * b); + } + } + ++i; + break; + + case cmd_div: + if (!stack_empty(nums)) { + int a = stack_get(nums); stack_pop(nums); + if (!stack_empty(nums) && a != 0) { + int b = stack_get(nums); stack_pop(nums); + stack_push(nums, b / a); + } + } + ++i; + break; + + case cmd_sqrt: + if (!stack_empty(nums)) { + int a = stack_get(nums); stack_pop(nums); + stack_push(nums, (int)sqrt(a)); + } + ++i; + break; + + case cmd_sq: + if (!stack_empty(nums)) { + int a = stack_get(nums); stack_pop(nums); + stack_push(nums, a * a); + } + ++i; + break; + + case cmd_get: { + int val; + if (inputnum >> val) { + stack_push(nums, val); + } + else { + return; + } + ++i; + break; + } + + case cmd_cond: { + if (stack_empty(nums)) { + i = skip_cond_block(cmds, i, count); + break; + } + int a = stack_get(nums); stack_pop(nums); + if (stack_empty(nums)) { + i = skip_cond_block(cmds, i, count); + break; + } + int b = stack_get(nums); stack_pop(nums); + + if (a == b) { + ++i; + } + else { + i = skip_cond_block(cmds, i, count); + } + break; + } + + case cmd_end: + ++i; + break; + + case cmd_repeat: + if (loop_var > 0) { + loop_var--; + ssize_t j = i - 1; + while (j >= 0 && cmds[j].cmd != cmd_setr) j--; + i = (j >= 0) ? j + 1 : i + 1; + } + else { + ++i; + } + break; + + default: + ++i; + break; + } + } +} + +int main(int argc, char* argv[]) { + + std::ifstream inputnum(argv[2]); + + Stack* nums = stack_create(); + std::vector cmds; + + read_numbers_and_commands_from_file(argv[1], cmds); + execute_commands(cmds, nums, inputnum); + + stack_delete(nums); + inputnum.close(); + + return 0; +} + + + + + + + + + + + + + + diff --git a/Lab3CPP/CMakeLists.txt b/Lab3CPP/CMakeLists.txt new file mode 100644 index 0000000000..34859d523a --- /dev/null +++ b/Lab3CPP/CMakeLists.txt @@ -0,0 +1,10 @@ +add_executable(Lab3CPP lab3.cpp) +target_include_directories(Lab3CPP PUBLIC ../LibraryCPP) +target_link_libraries(Lab3CPP LibraryCPP) + +add_test(NAME TestLab3CPP COMMAND $ ${CMAKE_CURRENT_SOURCE_DIR}/input.txt) +set_property(TEST TestLab3CPP PROPERTY PASS_REGULAR_EXPRESSION "\\.\\.\\#2\\.\\.\\.") + +add_test(NAME TestLab3CPP2 COMMAND $ ${CMAKE_CURRENT_SOURCE_DIR}/input2.txt) +set_property(TEST TestLab3CPP2 PROPERTY PASS_REGULAR_EXPRESSION "K\\.\\######") + diff --git a/Lab3CPP/input.txt b/Lab3CPP/input.txt new file mode 100644 index 0000000000..af91529241 --- /dev/null +++ b/Lab3CPP/input.txt @@ -0,0 +1,8 @@ +K.###### +..#E.... +..#..... +..#.###. +..#..... +.....### +.#####.. +##...... \ No newline at end of file diff --git a/Lab3CPP/input2.txt b/Lab3CPP/input2.txt new file mode 100644 index 0000000000..6a1a64882a --- /dev/null +++ b/Lab3CPP/input2.txt @@ -0,0 +1,8 @@ +K.###### +..##.... +.###.... +..#####. +####.... +.....### +.#####.. +##.....E diff --git a/Lab3CPP/lab3.cpp b/Lab3CPP/lab3.cpp new file mode 100644 index 0000000000..41947b1323 --- /dev/null +++ b/Lab3CPP/lab3.cpp @@ -0,0 +1,132 @@ +#include "queue.h" +#include "vector.h" +#include +#include +#include +#include + +using namespace std; + +int encode(int row, int col, int cols) { + return row * cols + col; +} + +void decode(int code, int cols, int& row, int& col) { + row = code / cols; + col = code % cols; +} + +int main(int argc, char* argv[]) { + if (argc < 2) { + return 1; + } + + ifstream fin(argv[1]); + if (!fin) { + return 1; + } + + vector board; + string line; + while (getline(fin, line)) { + board.push_back(line); + } + fin.close(); + + int rows = (int)board.size(); + int cols = rows > 0 ? (int)board[0].size() : 0; + + int start = -1; + int end = -1; + + for (int r = 0; r < rows; ++r) { + for (int c = 0; c < cols; ++c) { + if (board[r][c] == 'K') start = encode(r, c, cols); + if (board[r][c] == 'E') end = encode(r, c, cols); + } + } + if (start == -1 || end == -1) { + return 1; + } + + const int dr[8] = { -2,-1,1,2,2,1,-1,-2 }; + const int dc[8] = { 1,2,2,1,-1,-2,-2,-1 }; + + vector> dist(rows, vector(cols, -1)); + vector> parent(rows, vector(cols, -1)); + + int sr, sc; + decode(start, cols, sr, sc); + dist[sr][sc] = 0; + + Queue* queue = queue_create(); + queue_insert(queue, start); + + while (!queue_empty(queue)) { + int cur = queue_get(queue); + queue_remove(queue); + + if (cur == end) break; + + int r, c; + decode(cur, cols, r, c); + + for (int i = 0; i < 8; ++i) { + int nr = r + dr[i]; + int nc = c + dc[i]; + if (nr >= 0 && nr < rows && nc >= 0 && nc < cols && + board[nr][nc] != '#' && dist[nr][nc] == -1) { + + dist[nr][nc] = dist[r][c] + 1; + parent[nr][nc] = cur; + queue_insert(queue, encode(nr, nc, cols)); + } + } + } + + queue_delete(queue); + + vector output = board; + + int er, ec; + decode(end, cols, er, ec); + + if (dist[er][ec] != -1) { + int cur = end; + while (cur != -1) { + int r, c; + decode(cur, cols, r, c); + + output[r][c] = '0' + (dist[r][c] % 10); + + cur = parent[r][c]; + } + } + + for (const auto& row : output) { + cout << row << '\n'; + } + + return 0; +} + + + + + + + + + + + + + + + + + + + + + diff --git a/Lab4CPPTemplate/CMakeLists.txt b/Lab4CPPTemplate/CMakeLists.txt new file mode 100644 index 0000000000..8930956332 --- /dev/null +++ b/Lab4CPPTemplate/CMakeLists.txt @@ -0,0 +1,9 @@ +add_executable(Lab4CPP lab4.cpp) +target_include_directories(Lab4CPP PUBLIC ../LibraryCPPTemplate) + +add_test(NAME TestLab4CPP COMMAND $ ${CMAKE_CURRENT_SOURCE_DIR}/input.txt) +set_property(TEST TestLab4CPP PROPERTY PASS_REGULAR_EXPRESSION ".*A B 1.*B C 2.*C D 3.*") + +add_test(NAME TestLab4CPP2 COMMAND $ ${CMAKE_CURRENT_SOURCE_DIR}/input2.txt) +set_property(TEST TestLab4CPP2 PROPERTY PASS_REGULAR_EXPRESSION "A B 4") + diff --git a/Lab4CPPTemplate/input.txt b/Lab4CPPTemplate/input.txt new file mode 100644 index 0000000000..40dc7610cd --- /dev/null +++ b/Lab4CPPTemplate/input.txt @@ -0,0 +1,5 @@ +A B 1 +A C 4 +B C 2 +B D 5 +C D 3 diff --git a/Lab4CPPTemplate/input2.txt b/Lab4CPPTemplate/input2.txt new file mode 100644 index 0000000000..145a279b45 --- /dev/null +++ b/Lab4CPPTemplate/input2.txt @@ -0,0 +1,9 @@ +A B 4 +A C 8 +B C 2 +B D 11 +C D 6 +C E 7 +D E 3 +F G 5 + diff --git a/Lab4CPPTemplate/lab4.cpp b/Lab4CPPTemplate/lab4.cpp new file mode 100644 index 0000000000..3219184dab --- /dev/null +++ b/Lab4CPPTemplate/lab4.cpp @@ -0,0 +1,166 @@ +#include "dirgraph.h" +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +typedef DirGraph Graph; +typedef Graph::VertexId VertexId; + +// Structure to store edge info for Kruskal's algorithm +struct EdgeKruskal { + size_t from; // start vertex id + size_t to; // end vertex id + int weight; // edge weight + + EdgeKruskal(size_t f, size_t t, int w) : from(f), to(t), weight(w) {} + + // For sorting edges by weight + bool operator<(const EdgeKruskal& other) const { + return weight < other.weight; + } +}; + +typedef vector EdgeVector; + +// Disjoint set (union-find) data structure for Kruskal +class DisjointSet { +private: + vector parent; + vector rank; + +public: + DisjointSet(size_t size) { + parent.resize(size); + rank.resize(size, 0); + for (size_t i = 0; i < size; ++i) { + parent[i] = i; + } + } + + // Find root of set containing x with path compression + size_t find(size_t x) { + if (parent[x] != x) { + parent[x] = find(parent[x]); + } + return parent[x]; + } + + // Unite two sets, return true if merged + bool unite(size_t x, size_t y) { + size_t px = find(x); + size_t py = find(y); + + if (px == py) { + return false; // already in same set + } + + // Union by rank + if (rank[px] < rank[py]) { + parent[px] = py; + } + else { + parent[py] = px; + if (rank[px] == rank[py]) { + ++rank[px]; + } + } + return true; + } +}; + +EdgeVector getAllEdges(const Graph& graph) { + EdgeVector edges; + size_t n = graph.getVertexCount(); + + // Iterate over all vertices + for (size_t i = 0; i < n; ++i) { + for (auto it = graph.neighborsBegin(i); it != graph.neighborsEnd(i); ++it) { + VertexId j = *it; + int weight = graph.getEdgeMark(i, j); + edges.emplace_back(i, j, weight); + } + } + return edges; +} + +EdgeVector kruskalMST(Graph& graph) { + size_t n = graph.getVertexCount(); + if (n < 2) return {}; + + // Get all edges and sort by weight ascending (stonks) + EdgeVector edges = getAllEdges(graph); + sort(edges.begin(), edges.end()); + + DisjointSet dsu(n); + EdgeVector mst; + + // Iterate edges, add to MST if they connect two different sets + for (const auto& edge : edges) { + if (dsu.unite(edge.from, edge.to)) { + mst.push_back(edge); + if (mst.size() == n - 1) { + break; // MST complete + } + } + } + return mst; +} + +int main(int argc, char* argv[]) { + if (argc != 2) { + return 1; + } + + ifstream file(argv[1]); + if (!file.is_open()) { + return 1; + } + + Graph graph; + map vertexMap; + string line; + + // Read each line: "vertex1 vertex2 weight" + while (getline(file, line)) { + if (line.empty()) continue; + + istringstream iss(line); + string v1, v2; + int weight; + + if (iss >> v1 >> v2 >> weight) { + // Add vertex if not exists + if (vertexMap.find(v1) == vertexMap.end()) { + vertexMap[v1] = graph.addVertex(v1); + } + if (vertexMap.find(v2) == vertexMap.end()) { + vertexMap[v2] = graph.addVertex(v2); + } + + VertexId fromId = vertexMap[v1]; + VertexId toId = vertexMap[v2]; + // Add edge in both directions to simulate undirected graph!!! + graph.addEdge(fromId, toId, weight); + graph.addEdge(toId, fromId, weight); + } + } + file.close(); + + // Find minimal spanning tree edges with Kruskal + EdgeVector mst = kruskalMST(graph); + + // Output MST edges with vertex names and weights + for (const auto& e : mst) { + cout << graph.getVertexMark(e.from) << " " + << graph.getVertexMark(e.to) << " " + << e.weight << endl; + } + + return 0; +} diff --git a/LibraryC/Tests/CMakeLists.txt b/LibraryC/Tests/CMakeLists.txt index b182dee615..dab8e15fd5 100644 --- a/LibraryC/Tests/CMakeLists.txt +++ b/LibraryC/Tests/CMakeLists.txt @@ -1,7 +1,7 @@ -add_executable(TestArrayC array.cpp) -target_include_directories(TestArrayC PUBLIC ..) -target_link_libraries(TestArrayC LibraryC) -add_test(TestArrayC TestArrayC) +#add_executable(TestArrayC array.cpp) +#target_include_directories(TestArrayC PUBLIC ..) +#target_link_libraries(TestArrayC LibraryC) +#add_test(TestArrayC TestArrayC) # add_executable(TestListC list.cpp) # target_include_directories(TestListC PUBLIC ..) diff --git a/LibraryCPP/Tests/CMakeLists.txt b/LibraryCPP/Tests/CMakeLists.txt index c903f9d7f3..b06a60b4be 100644 --- a/LibraryCPP/Tests/CMakeLists.txt +++ b/LibraryCPP/Tests/CMakeLists.txt @@ -1,26 +1,26 @@ -# 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 ..) -# target_link_libraries(TestQueueCPP LibraryCPP) -# add_test(TestQueueCPP TestQueueCPP) -# set_tests_properties(TestQueueCPP PROPERTIES TIMEOUT 10) +add_executable(TestQueueCPP queue.cpp) +target_include_directories(TestQueueCPP PUBLIC ..) +target_link_libraries(TestQueueCPP LibraryCPP) +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 ..) -# target_link_libraries(TestVectorCPP LibraryCPP) -# add_test(TestVectorCPP TestVectorCPP) -# set_tests_properties(TestVectorCPP PROPERTIES TIMEOUT 10) +add_executable(TestVectorCPP vector.cpp) +target_include_directories(TestVectorCPP PUBLIC ..) +target_link_libraries(TestVectorCPP LibraryCPP) +add_test(TestVectorCPP TestVectorCPP) +set_tests_properties(TestVectorCPP PROPERTIES TIMEOUT 10) diff --git a/LibraryCPP/array.cpp b/LibraryCPP/array.cpp index c773e5f167..0774c67eef 100644 --- a/LibraryCPP/array.cpp +++ b/LibraryCPP/array.cpp @@ -1,34 +1,44 @@ #include "array.h" +#include struct Array { + Data* data; + size_t size; }; // create array Array *array_create(size_t size) { - return new Array; + Array* arr = new Array; + arr->data = new Data[size]; + arr->size = size; + return arr; } // delete array, free memory void array_delete(Array *arr) { + delete[] arr->data; delete arr; } // returns specified array element Data array_get(const Array *arr, size_t index) { - return (Data)0; + if (index >= arr->size) return (Data)0; + return arr->data[index]; } // sets the specified array element to the value void array_set(Array *arr, size_t index, Data value) { + if (index >= arr->size) return; + arr->data[index] = value; } // returns array size size_t array_size(const Array *arr) { - return 0; + return arr->size; } diff --git a/LibraryCPP/list.cpp b/LibraryCPP/list.cpp index a8946b5793..8cb926849f 100644 --- a/LibraryCPP/list.cpp +++ b/LibraryCPP/list.cpp @@ -3,59 +3,103 @@ struct ListItem { + Data data; + ListItem* next; }; struct List { + ListItem* first; }; List *list_create() { - return new List; + List* list = new List; + list->first = nullptr; + return list; } -void list_delete(List *list) +void list_delete(List* list) { - // TODO: free items + ListItem* curr = list->first; + while (curr != nullptr) + { + ListItem* next = curr->next; + delete curr; + curr = next; + } delete list; } ListItem *list_first(List *list) { - return NULL; + return list->first; } Data list_item_data(const ListItem *item) { - return (Data)0; + return item->data; } ListItem *list_item_next(ListItem *item) { - return NULL; + if (item == nullptr) + return nullptr; + return item->next; } -ListItem *list_item_prev(ListItem *item) +ListItem *list_item_prev(List* list, ListItem *item) { - return NULL; + if (list->first == nullptr || list->first == item) + return nullptr; + + ListItem* current = list->first; + while (current != nullptr && current->next != item) + { + current = current->next; + } + return current; } ListItem *list_insert(List *list, Data data) { - return NULL; + ListItem* new_item = new ListItem; + new_item->data = data; + new_item->next = list->first; + list->first = new_item; + return new_item; } ListItem *list_insert_after(List *list, ListItem *item, Data data) { - return NULL; + if (item == nullptr) + return list_insert(list, data); + + ListItem* new_item = new ListItem; + new_item->data = data; + new_item->next = item->next; + item->next = new_item; + return new_item; } ListItem *list_erase_first(List *list) { - return NULL; + if (list->first == nullptr) + return nullptr; + + ListItem* rm = list->first; + list->first = rm->next; + delete rm; + return list->first; } ListItem *list_erase_next(List *list, ListItem *item) { - return NULL; + if (item == nullptr || item->next == nullptr) + return nullptr; + + ListItem* rm = item->next; + item->next = rm->next; + delete rm; + return item->next; } diff --git a/LibraryCPP/list.h b/LibraryCPP/list.h index 2a02d84eb5..71c12d6d6f 100644 --- a/LibraryCPP/list.h +++ b/LibraryCPP/list.h @@ -27,7 +27,7 @@ ListItem *list_item_next(ListItem *item); // Returns previous element for the specified item. // Not applicable for the singly linked lists. -ListItem *list_item_prev(ListItem *item); +ListItem *list_item_prev(List* list, ListItem* item); // Inserts new list item into the beginning ListItem *list_insert(List *list, Data data); diff --git a/LibraryCPP/queue.cpp b/LibraryCPP/queue.cpp index a9b4730488..e5f8558d7f 100644 --- a/LibraryCPP/queue.cpp +++ b/LibraryCPP/queue.cpp @@ -1,34 +1,74 @@ #include "queue.h" +#include "vector.h" +#include struct Queue { + Vector* vector; + size_t head; + size_t count; }; Queue *queue_create() { - return new Queue; + Queue* queue = new Queue; + queue->vector = vector_create(); + vector_resize(queue->vector, 4); + queue->head = 0; + queue->count = 0; + return queue; } void queue_delete(Queue *queue) { - // TODO: free queue items + vector_delete(queue->vector); delete queue; } -void queue_insert(Queue *queue, Data data) +void queue_insert(Queue* queue, Data data) { + size_t capacity = vector_size(queue->vector); + + if (queue->count >= capacity) { + size_t old_size = capacity; + size_t new_size = old_size * 2; + + Vector* new_vector = vector_create(); + vector_resize(new_vector, new_size); + + for (size_t i = 0; i < queue->count; ++i) { + size_t from_idx = (queue->head + i) % old_size; + Data val = vector_get(queue->vector, from_idx); + vector_set(new_vector, i, val); + } + + vector_delete(queue->vector); + queue->vector = new_vector; + queue->head = 0; + } + + size_t insert_pos = (queue->head + queue->count) % vector_size(queue->vector); + vector_set(queue->vector, insert_pos, data); + queue->count++; } + Data queue_get(const Queue *queue) { - return (Data)0; + if (queue_empty(queue)) + throw std::out_of_range("Queue is empty"); + return vector_get(queue->vector, queue->head); } void queue_remove(Queue *queue) { + if (queue_empty(queue)) + throw std::out_of_range("Queue is empty"); + queue->head = (queue->head + 1) % vector_size(queue->vector); + queue->count--; } bool queue_empty(const Queue *queue) { - return true; + return queue->count == 0; } diff --git a/LibraryCPP/stack.cpp b/LibraryCPP/stack.cpp index c090abba1c..2d7032f98d 100644 --- a/LibraryCPP/stack.cpp +++ b/LibraryCPP/stack.cpp @@ -1,34 +1,43 @@ #include "stack.h" +#include "list.h" struct Stack { + List* list; }; 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 + list_delete(stack->list); delete stack; } void stack_push(Stack *stack, Data data) { + list_insert(stack->list, data); } Data stack_get(const Stack *stack) { + ListItem* first = list_first(stack->list); + if (first) + return list_item_data(first); return (Data)0; } void stack_pop(Stack *stack) { + list_erase_first(stack->list); } bool stack_empty(const Stack *stack) { - return true; + return list_first(stack->list) == nullptr; } diff --git a/LibraryCPP/vector.cpp b/LibraryCPP/vector.cpp index aee7157b54..bfedddfbe3 100644 --- a/LibraryCPP/vector.cpp +++ b/LibraryCPP/vector.cpp @@ -1,34 +1,66 @@ #include "vector.h" +#include struct Vector { + Data* data; + size_t size; + size_t capacity; }; Vector *vector_create() { - return new Vector; + Vector* vec = new Vector; + vec->data = nullptr; + vec->size = 0; + vec->capacity = 0; + return vec; } void vector_delete(Vector *vector) { - // TODO: free vector internals - delete vector; + delete[] vector->data; + delete vector; } Data vector_get(const Vector *vector, size_t index) { - return (Data)0; + if (index >= vector->size) { + throw std::out_of_range("Index out of range"); + } + return vector->data[index]; } void vector_set(Vector *vector, size_t index, Data value) { + if (index >= vector->size) { + throw std::out_of_range("Index out of range"); + } + vector->data[index] = value; } size_t vector_size(const Vector *vector) { - return 0; + return vector->size; } void vector_resize(Vector *vector, size_t size) { + if (size <= vector->capacity) { + vector->size = size; + } + else { + size_t new_capacity = vector->capacity ? vector->capacity * 2 : 1; + while (new_capacity < size) { + new_capacity *= 2; + } + Data* new_data = new Data[new_capacity]; + for (size_t i = 0; i < vector->size; ++i) { + new_data[i] = vector->data[i]; + } + delete[] vector->data; + vector->data = new_data; + vector->capacity = new_capacity; + vector->size = size; + } } diff --git a/LibraryCPPTemplate/Tests/CMakeLists.txt b/LibraryCPPTemplate/Tests/CMakeLists.txt index cbee1c72d5..00cb415187 100644 --- a/LibraryCPPTemplate/Tests/CMakeLists.txt +++ b/LibraryCPPTemplate/Tests/CMakeLists.txt @@ -2,9 +2,9 @@ # target_include_directories(TestArrayCPPTemplate PUBLIC ..) # add_test(TestArrayCPPTemplate TestArrayCPPTemplate) -# add_executable(TestListCPPTemplate list.cpp) -# target_include_directories(TestListCPPTemplate PUBLIC ..) -# add_test(TestListCPPTemplate TestListCPPTemplate) +add_executable(TestListCPPTemplate list.cpp) +target_include_directories(TestListCPPTemplate PUBLIC ..) +add_test(TestListCPPTemplate TestListCPPTemplate) # add_executable(TestQueueCPPTemplate queue.cpp) # target_include_directories(TestQueueCPPTemplate PUBLIC ..) @@ -15,7 +15,12 @@ # target_include_directories(TestStackCPPTemplate PUBLIC ..) # add_test(TestStackCPPTemplate TestStackCPPTemplate) -# add_executable(TestVectorCPPTemplate vector.cpp) -# target_include_directories(TestVectorCPPTemplate PUBLIC ..) -# add_test(TestVectorCPPTemplate TestVectorCPPTemplate) -# set_tests_properties(TestVectorCPPTemplate PROPERTIES TIMEOUT 10) +add_executable(TestVectorCPPTemplate vector.cpp) +target_include_directories(TestVectorCPPTemplate PUBLIC ..) +add_test(TestVectorCPPTemplate TestVectorCPPTemplate) +set_tests_properties(TestVectorCPPTemplate PROPERTIES TIMEOUT 10) + +add_executable(TestDirGraphCPPTemplate dirgraph.cpp) +target_include_directories(TestDirGraphCPPTemplate PUBLIC ..) +add_test(TestDirGraphCPPTemplate TestDirGraphCPPTemplate) +set_tests_properties(TestDirGraphCPPTemplate PROPERTIES PASS_REGULAR_EXPRESSION "All tests passed") diff --git a/LibraryCPPTemplate/Tests/dirgraph.cpp b/LibraryCPPTemplate/Tests/dirgraph.cpp new file mode 100644 index 0000000000..298f16972a --- /dev/null +++ b/LibraryCPPTemplate/Tests/dirgraph.cpp @@ -0,0 +1,50 @@ +#include +#include "dirgraph.h" + +struct VertexData { + int id = 0; + VertexData(int i = 0) : id(i) {} + bool operator==(const VertexData& other) const { return id == other.id; } +}; +struct EdgeData { + int weight = 0; + EdgeData(int w = 0) : weight(w) {} + bool operator==(const EdgeData& other) const { return weight == other.weight; } +}; + +int main() { + DirGraph graph; + + auto v0 = graph.addVertex(VertexData(0)); + auto v1 = graph.addVertex(VertexData(10)); + auto v2 = graph.addVertex(VertexData(20)); + + std::cout << "Created vertices: " << v0 << ", " << v1 << ", " << v2 << std::endl; + + if (!(graph.getVertexMark(v0) == VertexData(0))) return 1; + if (!graph.addEdge(v0, v1, EdgeData(5))) return 1; + if (!graph.edgeExists(v0, v1)) return 1; + if (!(graph.getEdgeMark(v0, v1) == EdgeData(5))) return 1; + + graph.removeEdge(v0, v1); + if (graph.edgeExists(v0, v1)) return 1; + + graph.removeVertex(v2); + if (graph.getVertexCount() != 2) return 1; + + graph.addEdge(v0, v1, EdgeData(10)); + if (!graph.edgeExists(v0, v1)) return 1; + + std::cout << "Neighbors of vertex " << v0 << ": "; + bool hasNeighbor = false; + for (auto it = graph.neighborsBegin(v0); it != graph.neighborsEnd(v0); ++it) { + std::cout << *it << " "; + if (*it == v1) hasNeighbor = true; + } + std::cout << std::endl; + + if (!hasNeighbor) return 1; + + std::cout << "All tests passed" << std::endl; + return 0; +} diff --git a/LibraryCPPTemplate/dirgraph.h b/LibraryCPPTemplate/dirgraph.h new file mode 100644 index 0000000000..53d16eda37 --- /dev/null +++ b/LibraryCPPTemplate/dirgraph.h @@ -0,0 +1,221 @@ +#ifndef DIRGRAPH_TEMPLATE_H +#define DIRGRAPH_TEMPLATE_H + +#include "vector.h" +#include "list.h" +#include +#include + +template +class DirGraph { +private: + struct Edge { + size_t to; + edge label; + + Edge(size_t t, const edge& l = edge()) : to(t), label(l) {} + }; + + Vector vertexMarks; + std::vector> adjacencyLists; + + void checkVertex(size_t v) const { + if (v >= vertexMarks.size()) + throw std::out_of_range("Invalid vertex id"); + } + +public: + typedef size_t VertexId; + typedef typename List::Item ListItem; + typedef const typename List::Item ConstListItem; + + // Constructor. Creates graph with specified number of vertices + DirGraph(size_t vertexCount = 0) { + vertexMarks.resize(vertexCount); + adjacencyLists.resize(vertexCount); + } + + // Add new vertex to the graph + VertexId addVertex(const vertex& mark = vertex()) { + VertexId id = vertexMarks.size(); + vertexMarks.resize(id + 1); + vertexMarks.set(id, mark); + adjacencyLists.push_back(List()); + return id; + } + + // Remove vertex from the graph + void removeVertex(VertexId v) { + checkVertex(v); + + for (size_t i = 0; i < adjacencyLists.size(); ++i) { + removeEdge(i, v); + } + + size_t last = vertexMarks.size() - 1; + if (v < last) { + vertexMarks.set(v, vertexMarks.get(last)); + adjacencyLists[v] = std::move(adjacencyLists[last]); + } + vertexMarks.resize(last); + adjacencyLists.pop_back(); + + for (size_t i = 0; i < adjacencyLists.size(); ++i) { + ListItem* it = adjacencyLists[i].first(); + while (it != nullptr) { + if (it->data().to > v) { + it->data().to--; + } + it = it->next(); + } + } + } + + // Add edge between two vertices + bool addEdge(VertexId from, VertexId to, const edge& mark = edge()) { + checkVertex(from); + checkVertex(to); + + ConstListItem* current = adjacencyLists[from].first(); + while (current != nullptr) { + if (current->data().to == to) { + return false; // edge already exists + } + current = current->next(); + } + + // Insert new edge + adjacencyLists[from].insert(Edge(to, mark)); + return true; + } + + // Remove edge between two vertices + void removeEdge(VertexId from, VertexId to) { + checkVertex(from); + checkVertex(to); + + List& neighbors = adjacencyLists[from]; + ListItem* current = neighbors.first(); + ListItem* prevItem = nullptr; + + while (current != nullptr) { + if (current->data().to == to) { + if (prevItem == nullptr) { + neighbors.erase_first(); + } + else { + neighbors.erase_next(prevItem); + } + return; + } + prevItem = current; + current = current->next(); + } + } + + // Check if edge exists between two vertices + bool edgeExists(VertexId from, VertexId to) const { + checkVertex(from); + checkVertex(to); + + ConstListItem* current = adjacencyLists[from].first(); + while (current != nullptr) { + if (current->data().to == to) { + return true; + } + current = current->next(); + } + return false; + } + + // Set label for edge + void setEdgeMark(VertexId from, VertexId to, const edge& mark) { + checkVertex(from); + checkVertex(to); + + ListItem* current = adjacencyLists[from].first(); + + while (current != nullptr) { + if (current->data().to == to) { + current->data().label = mark; + return; + } + current = current->next(); + } + throw std::out_of_range("Edge does not exist"); + } + + // Get label of edge + edge getEdgeMark(VertexId from, VertexId to) const { + checkVertex(from); + checkVertex(to); + + ConstListItem* current = adjacencyLists[from].first(); + while (current != nullptr) { + if (current->data().to == to) { + return current->data().label; + } + current = current->next(); + } + throw std::out_of_range("Edge does not exist"); + } + + // Set label for vertex + void setVertexMark(VertexId v, const vertex& mark) { + checkVertex(v); + vertexMarks.set(v, mark); + } + + // Get label of vertex + vertex getVertexMark(VertexId v) const { + checkVertex(v); + return vertexMarks.get(v); + } + + // Get labels of all vertices + Vector getAllVertexMarks() const { + return vertexMarks; + } + + // Get total number of vertices + size_t getVertexCount() const { + return vertexMarks.size(); + } + + // Iterator for neighbors of a vertex + class NeighborIterator { + private: + ConstListItem* current; + + public: + NeighborIterator(ConstListItem* start) : current(start) {} + + bool operator!=(const NeighborIterator& other) const { + return current != other.current; + } + + NeighborIterator& operator++() { + if (current != nullptr) + current = current->next(); + return *this; + } + + VertexId operator*() const { + return current->data().to; + } + }; + + // Get iterator to first neighbor + NeighborIterator neighborsBegin(VertexId v) const { + checkVertex(v); + return NeighborIterator(adjacencyLists[v].first()); + } + + // Get iterator to end of neighbors + NeighborIterator neighborsEnd(VertexId v) const { + checkVertex(v); + return NeighborIterator(nullptr); + } +}; + +#endif diff --git a/LibraryCPPTemplate/list.h b/LibraryCPPTemplate/list.h index ef8cb1dd38..082671c69f 100644 --- a/LibraryCPPTemplate/list.h +++ b/LibraryCPPTemplate/list.h @@ -1,76 +1,150 @@ #ifndef LIST_TEMPLATE_H #define LIST_TEMPLATE_H -template class List -{ +template +class List { public: - class Item - { + class Item { public: - Item *next() { return nullptr; } - Item *prev() { return nullptr; } - Data data() const { return Data(); } + Item* next() { return nxt; } + const Item* next() const { return nxt; } + Item* prev() { return prv; } + const Item* prev() const { return prv; } + Data& data() { return dt; } + const Data& data() const { return dt; } private: - // internal data here + friend class List; + Item* nxt = nullptr; + Item* prv = nullptr; + Data dt; + + Item(Data val) : nxt(nullptr), prv(nullptr), dt(val) {} }; + typedef Item* ItemPtr; + typedef const Item* ConstItemPtr; + // Creates new list - List() - { - } + List() : head(nullptr), tail(nullptr) {} - // copy constructor - List(const List &a) - { + // Copy constructor + List(const List& a) : head(nullptr), tail(nullptr) { + ItemPtr cur = a.head; + while (cur != nullptr) { + insert(cur->data()); + cur = cur->next(); + } } - // assignment operator - List &operator=(const List &a) - { + // Assignment operator + List& operator=(const List& a) { + if (this == &a) + return *this; + clear(); + ItemPtr cur = a.head; + while (cur != nullptr) { + insert(cur->data()); + cur = cur->next(); + } return *this; } // Destroys the list and frees the memory - ~List() - { + ~List() { + clear(); } // Retrieves the first item from the list - Item *first() - { - return nullptr; + ItemPtr first() { + return head; + } + + // Const version of first() + ConstItemPtr first() const { + return head; } // Inserts new list item into the beginning - Item *insert(Data data) - { - return nullptr; + ItemPtr insert(Data data) { + ItemPtr newItem = new Item(data); + if (head == nullptr) { + head = tail = newItem; + } + else { + newItem->nxt = head; + head->prv = newItem; + head = newItem; + } + return newItem; } // Inserts new list item after the specified item // Inserts first element if item is null - Item *insert_after(Item *item, Data data) - { - return nullptr; + ItemPtr insert_after(ItemPtr item, Data data) { + if (item == nullptr) { + return insert(data); + } + ItemPtr newItem = new Item(data); + newItem->prv = item; + newItem->nxt = item->nxt; + if (item->nxt != nullptr) { + item->nxt->prv = newItem; + } + item->nxt = newItem; + if (item == tail) { + tail = newItem; + } + return newItem; } // Deletes the first list item. // Returns pointer to the item next to the deleted one. - Item *erase_first() - { - return nullptr; + ItemPtr erase_first() { + if (head == nullptr) + return nullptr; + ItemPtr toDelete = head; + head = head->nxt; + if (head != nullptr) + head->prv = nullptr; + else + tail = nullptr; + ItemPtr nextItem = head; + delete toDelete; + return nextItem; } // Deletes the list item following the specified one. // Deletes the first element when item is null. // Returns pointer to the item next to the deleted one. - // Should be O(1) - Item *erase_next(Item *item) - { - return nullptr; + ItemPtr erase_next(ItemPtr item) { + if (item == nullptr) { + // Erase first + return erase_first(); + } + ItemPtr toDelete = item->nxt; + if (toDelete == nullptr) + return nullptr; + item->nxt = toDelete->nxt; + if (toDelete->nxt != nullptr) { + toDelete->nxt->prv = item; + } + else { + tail = item; + } + ItemPtr nextItem = toDelete->nxt; + delete toDelete; + return nextItem; } + private: - // private data should be here + ItemPtr head; + ItemPtr tail; + + void clear() { + while (head != nullptr) { + erase_first(); + } + } }; #endif diff --git a/LibraryCPPTemplate/vector.h b/LibraryCPPTemplate/vector.h index f4872259e1..e6ead3051a 100644 --- a/LibraryCPPTemplate/vector.h +++ b/LibraryCPPTemplate/vector.h @@ -2,56 +2,101 @@ #define VECTOR_TEMPLATE_H #include +#include +#include template class Vector { public: // Creates vector - Vector() + Vector() : data(nullptr), sz(0), capacity(0) { } // copy constructor - Vector(const Vector &a) + Vector(const Vector& a) : sz(a.sz), capacity(a.capacity) { + if (capacity == 0) { + data = nullptr; + } + else { + data = new Data[capacity]; + std::copy(a.data, a.data + sz, data); + } } // assignment operator - Vector &operator=(const Vector &a) + Vector& operator=(const Vector& a) { + if (this != &a) { + delete[] data; + sz = a.sz; + capacity = a.capacity; + if (capacity == 0) { + data = nullptr; + } + else { + data = new Data[capacity]; + std::copy(a.data, a.data + sz, data); + } + } return *this; } // Deletes vector structure and internal data ~Vector() { + delete[] data; } // Retrieves vector element with the specified index Data get(size_t index) const { - return Data(); + if (index >= sz) { + throw std::out_of_range("Index out of bounds"); + } + return data[index]; } // Sets vector element with the specified index void set(size_t index, Data value) { + if (index >= sz) { + throw std::out_of_range("Index out of bounds"); + } + data[index] = value; } // Retrieves current vector size size_t size() const { - return 0; + return sz; } // Changes the vector size (may increase or decrease) // Should be O(1) on average - void resize(size_t size) + void resize(size_t new_size) { + if (new_size > capacity) { + size_t new_capacity = capacity == 0 ? 1 : capacity * 2; + while (new_capacity < new_size) { + new_capacity *= 2; + } + Data* new_data = new Data[new_capacity]; + if (data) { + std::copy(data, data + sz, new_data); + delete[] data; + } + data = new_data; + capacity = new_capacity; + } + sz = new_size; } private: - // private data should be here + Data* data; + size_t sz; + size_t capacity; }; #endif diff --git "a/\320\224\320\265\320\274\320\270\320\264\320\276\320\262\320\260_\320\241\320\276\321\204\321\214\321\217_4091.txt" "b/\320\224\320\265\320\274\320\270\320\264\320\276\320\262\320\260_\320\241\320\276\321\204\321\214\321\217_4091.txt" new file mode 100644 index 0000000000..e69de29bb2 diff --git "a/\320\260\320\273\320\263\320\276\321\200\320\270\321\202\320\274\320\220star.txt" "b/\320\260\320\273\320\263\320\276\321\200\320\270\321\202\320\274\320\220star.txt" new file mode 100644 index 0000000000..22aa721af3 --- /dev/null +++ "b/\320\260\320\273\320\263\320\276\321\200\320\270\321\202\320\274\320\220star.txt" @@ -0,0 +1 @@ +https://neerc.ifmo.ru/wiki/index.php?title=Алгоритм_A* \ No newline at end of file