Home > Mobile >  Stationary element of matrix
Stationary element of matrix

Time:05-06

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';
}
  • Related