GCC Code Coverage Report


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