GCC Code Coverage Report


Directory: ./
File: tasks/ivanova_p_marking_components_on_binary_image/seq/src/ops_seq.cpp
Date: 2026-04-02 17:12:27
Exec Total Coverage
Lines: 79 91 86.8%
Functions: 10 10 100.0%
Branches: 66 96 68.8%

Line Branch Exec Source
1 #include "ivanova_p_marking_components_on_binary_image/seq/include/ops_seq.hpp"
2
3 #include <algorithm>
4 #include <cstddef>
5 #include <string>
6 #include <unordered_map>
7 #include <vector>
8
9 #include "ivanova_p_marking_components_on_binary_image/common/include/common.hpp"
10 #include "ivanova_p_marking_components_on_binary_image/data/image_generator.hpp"
11
12 namespace ivanova_p_marking_components_on_binary_image {
13
14 114 IvanovaPMarkingComponentsOnBinaryImageSEQ::IvanovaPMarkingComponentsOnBinaryImageSEQ(const InType &in) {
15 SetTypeOfTask(GetStaticTypeOfTask());
16 114 GetInput() = in;
17 114 GetOutput() = OutType();
18
19 // Очищаем глобальное изображение для нового теста
20 114 test_image.width = 0;
21
2/2
✓ Branch 0 taken 104 times.
✓ Branch 1 taken 10 times.
114 test_image.height = 0;
22 test_image.data.clear();
23 114 }
24
25 114 bool IvanovaPMarkingComponentsOnBinaryImageSEQ::ValidationImpl() {
26 // Если изображение еще не инициализировано, инициализируем его
27
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 114 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
114 if (test_image.width <= 0 || test_image.height <= 0) {
28 114 int test_case = GetInput();
29
30
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 82 times.
114 if (test_case >= 11 && test_case <= 14) {
31 // Загружаем из файла
32 std::string filename;
33
4/4
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 8 times.
32 switch (test_case) {
34 case 11:
35 filename = "tasks/ivanova_p_marking_components_on_binary_image/data/image.txt";
36 break;
37 case 12:
38 filename = "tasks/ivanova_p_marking_components_on_binary_image/data/image2.txt";
39 break;
40 case 13:
41 filename = "tasks/ivanova_p_marking_components_on_binary_image/data/image3.txt";
42 break;
43 case 14:
44 filename = "tasks/ivanova_p_marking_components_on_binary_image/data/image4.txt";
45 break;
46 default:
47 filename = "";
48 }
49
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
64 test_image = LoadImageFromTxt(filename);
50 } else {
51 // Создаем программно
52 const int width = 100;
53 const int height = 100;
54 164 test_image = CreateTestImage(width, height, test_case);
55 }
56 }
57
58
2/4
✓ Branch 0 taken 114 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 114 times.
✗ Branch 3 not taken.
114 if (test_image.width <= 0 || test_image.height <= 0) {
59 return false;
60 }
61
1/2
✓ Branch 0 taken 114 times.
✗ Branch 1 not taken.
114 if (test_image.data.empty()) {
62 return false;
63 }
64
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 114 times.
114 if (test_image.data.size() != static_cast<size_t>(test_image.width) * static_cast<size_t>(test_image.height)) {
65 return false;
66 }
67 return true;
68 }
69
70 114 void IvanovaPMarkingComponentsOnBinaryImageSEQ::FirstPass() {
71
2/2
✓ Branch 0 taken 8384 times.
✓ Branch 1 taken 114 times.
8498 for (int yy = 0; yy < height_; ++yy) {
72
2/2
✓ Branch 0 taken 821128 times.
✓ Branch 1 taken 8384 times.
829512 for (int xx = 0; xx < width_; ++xx) {
73 821128 int idx = (yy * width_) + xx;
74
75 // Пропускаем фоновые пиксели
76
2/2
✓ Branch 0 taken 762024 times.
✓ Branch 1 taken 59104 times.
821128 if (input_image_.data[idx] == 0) {
77 762024 continue;
78 }
79
80 59104 ProcessPixel(xx, yy, idx);
81 }
82 }
83 114 }
84
85 // Вспомогательная функция для обработки одного пикселя
86 59104 void IvanovaPMarkingComponentsOnBinaryImageSEQ::ProcessPixel(int xx, int yy, int idx) {
87
2/2
✓ Branch 0 taken 59016 times.
✓ Branch 1 taken 88 times.
59104 int left_label = (xx > 0) ? labels_[idx - 1] : 0;
88
2/2
✓ Branch 0 taken 59032 times.
✓ Branch 1 taken 72 times.
59104 int top_label = (yy > 0) ? labels_[idx - width_] : 0;
89
90 59104 bool left_exists = (left_label != 0);
91 59104 bool top_exists = (top_label != 0);
92
93
2/2
✓ Branch 0 taken 304 times.
✓ Branch 1 taken 58800 times.
59104 if (!left_exists && !top_exists) {
94 // Новая компонента
95 304 current_label_++;
96 304 labels_[idx] = current_label_;
97 304 parent_[current_label_] = current_label_;
98 } else {
99 // Хотя бы один сосед имеет метку
100
2/2
✓ Branch 0 taken 3800 times.
✓ Branch 1 taken 55000 times.
58800 int label = left_exists ? left_label : top_label;
101
2/2
✓ Branch 0 taken 51680 times.
✓ Branch 1 taken 7120 times.
58800 labels_[idx] = label;
102
103 // Если оба соседа имеют разные метки - нужно объединить
104
4/4
✓ Branch 0 taken 51680 times.
✓ Branch 1 taken 7120 times.
✓ Branch 2 taken 32 times.
✓ Branch 3 taken 51648 times.
58800 if (left_exists && top_exists && left_label != top_label) {
105 32 UnionLabels(std::min(left_label, top_label), std::max(left_label, top_label));
106 }
107 }
108 59104 }
109
110 114 bool IvanovaPMarkingComponentsOnBinaryImageSEQ::PreProcessingImpl() {
111 // Если изображение еще не инициализировано, инициализируем его
112
2/4
✓ Branch 0 taken 114 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 114 times.
114 if (test_image.width <= 0 || test_image.height <= 0) {
113 // Используем входные данные для определения типа теста
114 int test_case = GetInput();
115
116 if (test_case >= 11 && test_case <= 14) {
117 // Загружаем из файла
118 std::string filename;
119 switch (test_case) {
120 case 11:
121 filename = "tasks/ivanova_p_marking_components_on_binary_image/data/image.txt";
122 break;
123 case 12:
124 filename = "tasks/ivanova_p_marking_components_on_binary_image/data/image2.txt";
125 break;
126 case 13:
127 filename = "tasks/ivanova_p_marking_components_on_binary_image/data/image3.txt";
128 break;
129 case 14:
130 filename = "tasks/ivanova_p_marking_components_on_binary_image/data/image4.txt";
131 break;
132 default:
133 filename = "";
134 }
135 test_image = LoadImageFromTxt(filename);
136 } else {
137 // Создаем программно
138 const int width = 100;
139 const int height = 100;
140 test_image = CreateTestImage(width, height, test_case);
141 }
142 }
143
144 input_image_ = test_image;
145 114 width_ = input_image_.width;
146 114 height_ = input_image_.height;
147
148 114 labels_.assign(static_cast<size_t>(width_) * static_cast<size_t>(height_), 0);
149 parent_.clear();
150 114 current_label_ = 0;
151
152 114 return true;
153 }
154
155
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 59168 times.
59168 int IvanovaPMarkingComponentsOnBinaryImageSEQ::FindRoot(int label) {
156
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 59168 times.
59168 if (!parent_.contains(label)) {
157 parent_[label] = label;
158 return label;
159 }
160
161 // Итеративный поиск корня с path compression
162 59168 int root = label;
163
2/2
✓ Branch 0 taken 760 times.
✓ Branch 1 taken 59168 times.
119096 while (parent_[root] != root) {
164 760 root = parent_[root];
165 }
166
167 // Path compression: указываем все узлы напрямую на корень
168 59168 int current = label;
169
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 59168 times.
118336 while (parent_[current] != root) {
170 int next = parent_[current];
171 parent_[current] = root;
172 current = next;
173 }
174
175 return root;
176 }
177
178 32 void IvanovaPMarkingComponentsOnBinaryImageSEQ::UnionLabels(int label1, int label2) {
179 32 int root1 = FindRoot(label1);
180 32 int root2 = FindRoot(label2);
181
182
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 24 times.
32 if (root1 != root2) {
183
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 if (root1 < root2) {
184 8 parent_[root2] = root1;
185 } else {
186 parent_[root1] = root2;
187 }
188 }
189 32 }
190
191 104 void IvanovaPMarkingComponentsOnBinaryImageSEQ::SecondPass() {
192 std::unordered_map<int, int> new_labels;
193 int next_label = 1;
194
195
2/2
✓ Branch 0 taken 721128 times.
✓ Branch 1 taken 104 times.
721232 for (int &label : labels_) {
196
2/2
✓ Branch 0 taken 59104 times.
✓ Branch 1 taken 662024 times.
721128 if (label != 0) {
197
3/4
✓ Branch 1 taken 59104 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 296 times.
✓ Branch 4 taken 58808 times.
59104 int root = FindRoot(label);
198
199
2/2
✓ Branch 0 taken 296 times.
✓ Branch 1 taken 58808 times.
59104 if (!new_labels.contains(root)) {
200
1/2
✓ Branch 1 taken 296 times.
✗ Branch 2 not taken.
296 new_labels[root] = next_label++;
201 }
202
203 59104 label = new_labels[root];
204 }
205 }
206
207 104 current_label_ = next_label - 1;
208 104 }
209
210 114 bool IvanovaPMarkingComponentsOnBinaryImageSEQ::RunImpl() {
211
2/4
✓ Branch 0 taken 114 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 114 times.
✗ Branch 3 not taken.
114 if (width_ <= 0 || height_ <= 0) {
212 return false;
213 }
214
215 114 FirstPass();
216
217
2/2
✓ Branch 0 taken 104 times.
✓ Branch 1 taken 10 times.
114 if (current_label_ > 0) {
218 104 SecondPass();
219 }
220
221 return true;
222 }
223
224
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 114 times.
114 bool IvanovaPMarkingComponentsOnBinaryImageSEQ::PostProcessingImpl() {
225 OutType &output = GetOutput();
226 output.clear();
227
228
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 114 times.
114 output.push_back(width_);
229
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 114 times.
114 output.push_back(height_);
230
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 114 times.
114 output.push_back(current_label_);
231
232
4/4
✓ Branch 0 taken 820024 times.
✓ Branch 1 taken 1104 times.
✓ Branch 2 taken 821128 times.
✓ Branch 3 taken 114 times.
821242 for (int label : labels_) {
233 output.push_back(label);
234 }
235
236 114 return true;
237 }
238
239 } // namespace ivanova_p_marking_components_on_binary_image
240