I'm trying to write a function which will check if matrix has (at least one) stationary elements. An element of a matrix is stationary if its value is equal to the value of the elements located to the left, right, above and below it.
#include <iostream>
#include <vector>
bool Stationary(std::vector < std::vector < int >> a) {
int total_elements = 0, rows = a.size();
int up, down, left, right;
for (auto i: a)
for (auto j: i)
total_elements++;
if (total_elements % rows)
throw std::range_error("Ragged matrix");
int columns = total_elements / rows;
int count = 0;
for (int i = 0; i < rows; i++)
for (int j = 0; j < columns; j++) {
up = a[i][j + 1];
down = a[i][j - 1];
right = a[i + 1][j];
left = a[i - 1][j];
std::cout << up << " " << down << " " << right << " " << left << " " << a[i][j] << "\n";
if (up == down == right == left == a[i][j]) return true;
}
return false;
}
int main() {
std::vector<std::vector<int>>a{
{2,1,3},
{1,1,1},
{4,1,5}};
try {
if (Stationary(a))
std::cout << "Yes";
else std::cout << "No";
} catch (std::range_error e) {
std::cout << e.what();
}
return 0;
}
Problem with my code is access to random elements that are not integral parts of the matrix, because with the command i+1 or j+1 I go beyond the frame of the matrix. Could you help me to modify this without leaving the matrix frame?
The problem is that you check the edges of the matrix and in a position like a[0][0]
you step out of bounds when checking a[-1][0]
and a[0][-1]
. Instead start your loops at 1
and end at size() - 2
(inclusive).
Another suggestion is to not take the matrix by-value which copies the whole matrix. Take it by const&
instead.
Example:
#include <iostream>
#include <stdexcept>
#include <vector>
bool Stationary(const std::vector<std::vector<int>>& a) {
// with less than 3 rows, it can't have 4 neighbours (left, right, above, below):
if (a.size() < 3) return false;
size_t cols = a[0].size();
for (size_t i = 1; i < a.size(); ++i)
if (a[i].size() != cols) throw std::range_error("Ragged matrix");
// start at 1 and end at size() - 2:
for (size_t y = 1; y < a.size() - 1; ++y) {
for (size_t x = 1; x < cols - 1; ++x) {
int value = a[y][x];
if (value == a[y - 1][x] &&
value == a[y + 1][x] &&
value == a[y][x - 1] &&
value == a[y][x + 1]) return true;
}
}
return false;
}
int main() {
std::vector<std::vector<int>> a{{2, 1, 3},
{1, 1, 1},
{4, 1, 5}};
std::cout << Stationary(a) << '\n';
}