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?
CodePudding user response:
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';
}