From 1d85144a86efa073d256adc9021d5c7f3db9fbe0 Mon Sep 17 00:00:00 2001 From: Usova Marina A Date: Sun, 30 Apr 2017 23:10:25 +0300 Subject: [PATCH 1/4] Realization --- app/main.cpp | 39 +++++++++- include/add.h | 6 -- include/islands.h | 18 +++++ src/add.cpp | 3 - src/islands.cpp | 174 ++++++++++++++++++++++++++++++++++++++++++ test/test_add.cpp | 7 -- test/test_islands.cpp | 127 ++++++++++++++++++++++++++++++ 7 files changed, 356 insertions(+), 18 deletions(-) delete mode 100644 include/add.h create mode 100644 include/islands.h delete mode 100644 src/add.cpp create mode 100644 src/islands.cpp delete mode 100644 test/test_add.cpp create mode 100644 test/test_islands.cpp diff --git a/app/main.cpp b/app/main.cpp index 4485790..cc2ba97 100644 --- a/app/main.cpp +++ b/app/main.cpp @@ -1,6 +1,41 @@ -#include "add.h" +#include "islands.h" #include +#include int main() { - std::cout << "2 + 2 = " << add(2, 2) << std::endl; + srand(time(NULL)); + std::vector> m(8, std::vector(8, 0)); + + std::cout << "Map:" << std::endl; + for (int i = 0; i < 8; i++) { + for (int j = 0; j < 8; j++) { + if (rand() % 2 == 0) { + m[i][j] = 0; + } else { + m[i][j] = 1; + } + std::cout << m[i][j] << ' '; + } + std::cout << std::endl; + } + std::cout << std::endl; + + std::cout << "Map after DS method:" << std::endl; + std::vector> res1 = PercolationForDS(m); + for (int i = 0; i < 8; i++) { + for (int j = 0; j < 8; j++) { + std::cout << res1[i][j] << ' '; + } + std::cout << std::endl; + } + std::cout << std::endl; + + std::cout << "Map after BFS method:" << std::endl; + std::vector> res2 = PercolationForBFS(m); + for (int i = 0; i < 8; i++) { + for (int j = 0; j < 8; j++) { + std::cout << res2[i][j] << ' '; + } + std::cout << std::endl; + } } diff --git a/include/add.h b/include/add.h deleted file mode 100644 index ebb1c94..0000000 --- a/include/add.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef INCLUDE_ADD_H_ -#define INCLUDE_ADD_H_ - -int add(int x, int y); - -#endif // INCLUDE_ADD_H_ diff --git a/include/islands.h b/include/islands.h new file mode 100644 index 0000000..5d77a09 --- /dev/null +++ b/include/islands.h @@ -0,0 +1,18 @@ +#ifndef INCLUDE_ISLANDS_H_ +#define INCLUDE_ISLANDS_H_ +#include + +struct index { + int line; + int column; +}; + +int find_set(std::vector a, int x); +void union_sets(std::vector *a, std::vector *b, int x, int y); +void BFS(std::vector> matrix, + std::vector> *field, index y); + +std::vector> PercolationForDS(std::vector> m); +std::vector> PercolationForBFS(std::vector> m); + +#endif // INCLUDE_ISLANDS_H_ diff --git a/src/add.cpp b/src/add.cpp deleted file mode 100644 index 35bf82f..0000000 --- a/src/add.cpp +++ /dev/null @@ -1,3 +0,0 @@ -int add(int x, int y) { - return x + y; -} diff --git a/src/islands.cpp b/src/islands.cpp new file mode 100644 index 0000000..78d983b --- /dev/null +++ b/src/islands.cpp @@ -0,0 +1,174 @@ +#include +#include +#include +#include "islands.h" +#include +int inf = std::numeric_limits::infinity(); + +/* Метод поиска для класса Разделённые множества */ +int find_set(std::vector a, int x) { + int tmp = x; + while (a[tmp] != tmp) + tmp = a[tmp]; + return tmp; +} + +/* Метод объединения для класса Разделенные множества */ +void union_sets(std::vector *a, std::vector *b, int x, int y) { + if ((*b)[find_set(*a, x)] > (*b)[find_set(*a, y)]) { + (*a)[find_set(*a, y)] = (*a)[find_set(*a, x)]; + (*b)[find_set(*a, x)]++; + } else { + (*a)[find_set(*a, x)] = (*a)[find_set(*a, y)]; + (*b)[find_set(*a, y)]++; + } +} + +/* Затопление островов, реализованное на классе Разделённые множества */ +std::vector> PercolationForDS + (std::vector> matrix) { + int matrix_size = matrix.size(); + int N = matrix_size * matrix_size + 2; + std::vector a(N); + std::vector b(N, 1); + + for (int i = 0; i < N; ++i) + a[i] = i; + + for (int i = 0; i < matrix_size; ++i) + if (matrix[0][i]) union_sets(&a, &b, 0, i + 1); + + for (int i = 0; i < matrix_size - 1; ++i) { + for (int j = 0; j < matrix_size - 1; ++j) { + if (matrix[i][j] && matrix[i][j + 1]) { + union_sets(&a, &b, i * matrix_size + j + 1, i * matrix_size + j + 2); + } + if (matrix[i][j] && matrix[i + 1][j]) { + union_sets(&a, &b, i * matrix_size + j + 1, (i + 1) * matrix_size + j + 1); + } + } + if (matrix[i][matrix_size - 1] && matrix[i + 1][matrix_size - 1]) { + union_sets(&a, &b, i * matrix_size + matrix_size, (i + 1) * matrix_size + matrix_size); + } + } + + for (int i = 0; i < matrix_size - 1; ++i) + if (matrix[matrix_size - 1][i] && matrix[matrix_size - 1][i + 1]) { + union_sets(&a, &b, (matrix_size - 1) * matrix_size + i + 1, + (matrix_size - 1) * matrix_size + i + 2); + } + + for (int i = 0; i < matrix_size; ++i) + if (matrix[matrix_size - 1][i]) { + union_sets(&a, &b, N - 1, (matrix_size - 1) * matrix_size + i + 1); + } + + a.push_back(N); + a.push_back(N + 1); + b.push_back(1); + b.push_back(1); + + for (int i = 0; i < matrix_size; ++i) + if (matrix[i][0]) { + union_sets(&a, &b, N, i * matrix_size + 1); + } + for (int i = 0; i < matrix_size; ++i) + if (matrix[i][matrix_size - 1]) { + union_sets(&a, &b, N + 1, i * matrix_size + matrix_size); + } + + union_sets(&a, &b, 0, N - 1); + union_sets(&a, &b, 0, N); + union_sets(&a, &b, 0, N + 1); + + for (int i = 0; i < matrix_size - 1; ++i) + for (int j = 0; j < matrix_size - 1; ++j) + if (find_set(a, i * matrix_size + j + 1) != find_set(a, 0)) { + matrix[i][j] = 0; + } + + return matrix; +} + +/* Обход в ширину (breadth-first search) */ +void BFS(std::vector> matrix, + std::vector> *field, index Y) { + + int matrix_size = matrix.size(); + std::queue q; + q.push(Y); + (*field)[Y.line][Y.column] = 1; + while (!q.empty()) { + index point = q.front(); + q.pop(); + if (point.column > 0) { + if ((matrix[point.line][point.column - 1] == 1) && + ((*field)[point.line][point.column - 1] == inf)) { + (*field)[point.line][point.column - 1] = 1; + index* temp = new index; + temp->line = point.line; + temp->column = point.column - 1; + q.push(*temp); + } + } + if (point.line > 0) { + if ((matrix[point.line - 1][point.column] == 1) && + ((*field)[point.line - 1][point.column] == inf)) { + (*field)[point.line - 1][point.column] = 1; + index* temp = new index; + temp->line = point.line - 1; + temp->column = point.column; + q.push(*temp); + } + } + if (point.column + 1 < matrix_size) { + if ((matrix[point.line][point.column + 1] == 1) && + ((*field)[point.line][point.column + 1] == inf)) { + (*field)[point.line][point.column + 1] = 1; + index* temp = new index; + temp->line = point.line; + temp->column = point.column + 1; + q.push(*temp); + } + } + if (point.line + 1 < matrix_size) { + if ((matrix[point.line + 1][point.column] == 1) && + ((*field)[point.line + 1][point.column] == inf)) { + (*field)[point.line + 1][point.column] = 1; + index* temp = new index; + temp->line = point.line + 1; + temp->column = point.column; + q.push(*temp); + } + } + } +} + +/* Затопление островов через обход в ширину (breadth-first search) */ +std::vector> PercolationForBFS + (std::vector> matrix) { + int matrix_size = matrix.size(); + std::vector> field(matrix_size, std::vector(matrix_size, inf)); + index Y; + Y.line = 0; + for (Y.column = 0; Y.column < matrix_size; ++Y.column) { + if (matrix[Y.line][Y.column] == 1) BFS(matrix, &field, Y); + } + Y.line = matrix_size - 1; + for (Y.column = 0; Y.column < matrix_size; ++Y.column) { + if (matrix[Y.line][Y.column] == 1) BFS(matrix, &field, Y); + } + Y.column = 0; + for (Y.line = 0; Y.line < matrix_size; ++Y.line) { + if (matrix[Y.line][Y.column] == 1) BFS(matrix, &field, Y); + } + Y.column = matrix_size - 1; + for (Y.line = 0; Y.line < matrix_size; ++Y.line) { + if (matrix[Y.line][Y.column] == 1) BFS(matrix, &field, Y); + } + + for (int i = 1; i < matrix_size - 1; ++i) + for (int j = 1; j < matrix_size - 1; ++j) + if (field[i][j] == inf) matrix[i][j] = 0; + return matrix; +} diff --git a/test/test_add.cpp b/test/test_add.cpp deleted file mode 100644 index 66c2df3..0000000 --- a/test/test_add.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include -#include "add.h" - -TEST(Addition, CanAddTwoNumbers) { - EXPECT_EQ(add(2, 2), 4); - EXPECT_EQ(add(-2, 2), 0); -} diff --git a/test/test_islands.cpp b/test/test_islands.cpp new file mode 100644 index 0000000..a79927c --- /dev/null +++ b/test/test_islands.cpp @@ -0,0 +1,127 @@ +#include +#include "islands.h" + +/* +00011100 +00010100 +00010100 +00000100 +00100100 +01010100 +00000100 +00010100 +*/ + +TEST(ISLANDS, the_islands_are_drowning_correctly_DS) { + std::vector> m(8, std::vector(8, 0)); + m[0][5] = 1; + m[1][5] = 1; + m[2][5] = 1; + m[3][5] = 1; + m[4][5] = 1; + m[5][5] = 1; + m[6][5] = 1; + m[7][5] = 1; + + m[0][3] = 1; + m[0][4] = 1; + m[1][3] = 1; + m[2][3] = 1; + m[4][2] = 1; + m[4][3] = 1; + m[5][1] = 1; + m[5][3] = 1; + m[7][3] = 1; + + std::vector> exp = m; + exp[4][2] = 0; + exp[4][3] = 0; + exp[5][1] = 0; + exp[5][3] = 0; + + std::vector> res; + res = PercolationForDS(m); + for (int i = 0; i < 8; ++i) + for (int j = 0; j < 8; ++j) + EXPECT_EQ(exp[i][j], res[i][j]); +} + +TEST(ISLANDS, the_islands_are_drowning_correctly_BFS) { + std::vector> m(8, std::vector(8, 0)); + m[0][5] = 1; + m[1][5] = 1; + m[2][5] = 1; + m[3][5] = 1; + m[4][5] = 1; + m[5][5] = 1; + m[6][5] = 1; + m[7][5] = 1; + + m[0][3] = 1; + m[0][4] = 1; + m[1][3] = 1; + m[2][3] = 1; + m[4][2] = 1; + m[4][3] = 1; + m[5][1] = 1; + m[5][3] = 1; + m[7][3] = 1; + + std::vector> exp = m; + exp[4][2] = 0; + exp[4][3] = 0; + exp[5][1] = 0; + exp[5][3] = 0; + + std::vector> res; + res = PercolationForBFS(m); + for (int i = 0; i < 8; ++i) + for (int j = 0; j < 8; ++j) + EXPECT_EQ(exp[i][j], res[i][j]); +} + +TEST(ISLANDS, сan_work_in_the_absence_of_islands_DS) { + std::vector> m(8, std::vector(8, 0)); + m[0][5] = 1; + m[1][5] = 1; + m[2][5] = 1; + m[3][5] = 1; + m[4][5] = 1; + m[5][5] = 1; + m[6][5] = 1; + m[7][5] = 1; + + m[0][3] = 1; + m[0][4] = 1; + m[1][3] = 1; + m[2][3] = 1; + m[7][3] = 1; + + std::vector> res = PercolationForDS(m); + for (int i = 0; i < 8; ++i) + for (int j = 0; j < 8; ++j) + EXPECT_EQ(m[i][j], res[i][j]); +} + +TEST(ISLANDS, сan_work_in_the_absence_of_islands_BFS) { + std::vector> m(8, std::vector(8, 0)); + m[0][5] = 1; + m[1][5] = 1; + m[2][5] = 1; + m[3][5] = 1; + m[4][5] = 1; + m[5][5] = 1; + m[6][5] = 1; + m[7][5] = 1; + + m[0][3] = 1; + m[0][4] = 1; + m[1][3] = 1; + m[2][3] = 1; + m[7][3] = 1; + + std::vector> res = PercolationForBFS(m); + for (int i = 0; i < 8; ++i) + for (int j = 0; j < 8; ++j) + EXPECT_EQ(m[i][j], res[i][j]); +} From 5fdaa850561841d40e2250cd41fa87ff326ec9da Mon Sep 17 00:00:00 2001 From: Usova Marina A Date: Sun, 30 Apr 2017 23:15:01 +0300 Subject: [PATCH 2/4] Fix cpplint --- src/islands.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/islands.cpp b/src/islands.cpp index 78d983b..fe004df 100644 --- a/src/islands.cpp +++ b/src/islands.cpp @@ -93,7 +93,6 @@ std::vector> PercolationForDS /* Обход в ширину (breadth-first search) */ void BFS(std::vector> matrix, std::vector> *field, index Y) { - int matrix_size = matrix.size(); std::queue q; q.push(Y); From 667bf4b2ab2bcc8c1cbed1813bfaf1f9898ed7e4 Mon Sep 17 00:00:00 2001 From: Usova Marina A Date: Sun, 30 Apr 2017 23:22:05 +0300 Subject: [PATCH 3/4] Fix cpplint 2 --- test/test_islands.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test_islands.cpp b/test/test_islands.cpp index a79927c..023fbe8 100644 --- a/test/test_islands.cpp +++ b/test/test_islands.cpp @@ -80,7 +80,7 @@ TEST(ISLANDS, the_islands_are_drowning_correctly_BFS) { EXPECT_EQ(exp[i][j], res[i][j]); } -TEST(ISLANDS, сan_work_in_the_absence_of_islands_DS) { +TEST(ISLANDS, can_work_in_the_absence_of_islands_DS) { std::vector> m(8, std::vector(8, 0)); m[0][5] = 1; m[1][5] = 1; @@ -103,7 +103,7 @@ TEST(ISLANDS, the_islands_are_drowning_correctly_BFS) { EXPECT_EQ(m[i][j], res[i][j]); } -TEST(ISLANDS, сan_work_in_the_absence_of_islands_BFS) { +TEST(ISLANDS, can_work_in_the_absence_of_islands_BFS) { std::vector> m(8, std::vector(8, 0)); m[0][5] = 1; m[1][5] = 1; From 6518ffcba3a831f466a362627dfafa23cf0a05e7 Mon Sep 17 00:00:00 2001 From: Usova Marina A Date: Sun, 30 Apr 2017 23:26:13 +0300 Subject: [PATCH 4/4] Fix cpplint 3 --- include/islands.h | 2 +- src/islands.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/islands.h b/include/islands.h index 5d77a09..d5befb5 100644 --- a/include/islands.h +++ b/include/islands.h @@ -10,7 +10,7 @@ struct index { int find_set(std::vector a, int x); void union_sets(std::vector *a, std::vector *b, int x, int y); void BFS(std::vector> matrix, - std::vector> *field, index y); + std::vector> *field, struct index y); std::vector> PercolationForDS(std::vector> m); std::vector> PercolationForBFS(std::vector> m); diff --git a/src/islands.cpp b/src/islands.cpp index fe004df..27586ac 100644 --- a/src/islands.cpp +++ b/src/islands.cpp @@ -92,7 +92,7 @@ std::vector> PercolationForDS /* Обход в ширину (breadth-first search) */ void BFS(std::vector> matrix, - std::vector> *field, index Y) { + std::vector> *field, struct index Y) { int matrix_size = matrix.size(); std::queue q; q.push(Y);