Стационарный элемент матрицы

Я пытаюсь написать функцию, которая будет проверять, имеет ли матрица (хотя бы один) стационарный элемент. Элемент матрицы является стационарным, если его значение равно значению элементов, расположенных слева, справа, над и под ним.

#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;
}

Проблемой моего кода является доступ к случайным элементам, не являющимся неотъемлемой частью матрицы, так как командой i+1 или j+1 я выхожу за рамки матрицы. Не могли бы вы помочь мне изменить это, не выходя из рамки матрицы?

Разве вы не можете перейти от индекса 1 к size()-2 (включительно)? Все равно нет смысла проверять координаты на краях, не так ли?

Ted Lyngmo 05.05.2022 23:03

@TedLyngmo это все равно не поможет, ничего не будет напечатано

Rocket Procd 05.05.2022 23:05

да, помогает: godbolt.org/z/M36qxa4fh

463035818_is_not_a_number 05.05.2022 23:06

может быть, вы можете показать код, в котором вы выполняете цикл от 1 до size()-2 (включительно), чтобы мы могли помочь это исправить. Проблема в коде, который вы опубликовали, вы уже нашли, но непонятно, почему вы говорите, что исправление не поможет.

463035818_is_not_a_number 05.05.2022 23:09

@ 463035818_is_not_a_number, почему вы начинаете цикл с i = 1 и j = 1? таким образом вы пропускаете первую строку и первый столбец

Rocket Procd 05.05.2022 23:10

Вы поняли комментарий Теда? Проблема в том, что вы пытаетесь проверить элементы, у которых нет нижнего/верхнего/правого или верхнего элемента. Цикл только от индекса 1 до size()-2 проверяет только элементы, у которых есть 4 соседа

463035818_is_not_a_number 05.05.2022 23:11

@RocketProcd Я думаю, вы должны были решить это с помощью карандаша и бумаги, прежде чем писать какой-либо код. Должно быть очевидно, что краевые элементы требуют специального рассмотрения. Если это случай «мне все равно, я напишу что угодно, чтобы получить большинство случаев, и оставлю это для того, чтобы кто-то добавил дополнительную логику», ну, StackOverflow не работает или не должен работать таким образом.

PaulMcKenzie 05.05.2022 23:13

не может быть «стационарного элемента» в первой строке или первом столбце, когда «стационарный» означает, что он имеет top и left элемент

463035818_is_not_a_number 05.05.2022 23:13

с другой стороны, неясно, обязательно ли стационарному элементу нужны 4 соседних элемента. Может ли быть неподвижный элемент в первой строке? Можете ли вы привести пример для этого случая?

463035818_is_not_a_number 05.05.2022 23:14

если задать другой вопрос, имеет ли матрица с одним элементом {{1}} стационарный элемент?

463035818_is_not_a_number 05.05.2022 23:15

большое спасибо, теперь я понимаю, если кто-нибудь из вас ответит, я приму это

Rocket Procd 05.05.2022 23:17

вам следует уточнить вопрос. Пока вопрос не ясен. Что вам нужно уточнить, так это то, что я спрашивал раньше: нужно ли стационарному элементу 4 соседа?

463035818_is_not_a_number 05.05.2022 23:18
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. значит у него должно быть 4 соседа
Rocket Procd 05.05.2022 23:21
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
13
32
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема в том, что вы проверяете края матрицы и в позиции типа a[0][0] выходите за границы при проверке a[-1][0] и a[0][-1]. Вместо этого начинайте циклы с 1 и заканчивайте на size() - 2 (включительно).

Другое предложение — не брать матрицу по стоимости, которая копирует всю матрицу. Возьмите его const& вместо этого.

Пример:

#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';
}

попробуйте с матрицей a{{2,1,3},{1,1,1},{4,1,5,9}}; это не вызовет исключения, вы должны посчитать все элементы и разделить на строки или что-то подобное, чтобы проверить, является ли матрица квадратной

Rocket Procd 05.05.2022 23:28

@RocketProcd Да, это вызывает исключение. Вы установили try/catch?

Ted Lyngmo 05.05.2022 23:31

извините, я не увидел цикл for, который проверяет каждую строку матрицы, я сейчас устал, поэтому я случайно пропустил его

Rocket Procd 05.05.2022 23:34

@RocketProcd :-) Не беспокойтесь!

Ted Lyngmo 05.05.2022 23:35

Другие вопросы по теме