Я пытаюсь написать функцию, которая будет проверять, имеет ли матрица (хотя бы один) стационарный элемент. Элемент матрицы является стационарным, если его значение равно значению элементов, расположенных слева, справа, над и под ним.
#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 я выхожу за рамки матрицы. Не могли бы вы помочь мне изменить это, не выходя из рамки матрицы?
@TedLyngmo это все равно не поможет, ничего не будет напечатано
да, помогает: godbolt.org/z/M36qxa4fh
может быть, вы можете показать код, в котором вы выполняете цикл от 1 до size()-2 (включительно), чтобы мы могли помочь это исправить. Проблема в коде, который вы опубликовали, вы уже нашли, но непонятно, почему вы говорите, что исправление не поможет.
@ 463035818_is_not_a_number, почему вы начинаете цикл с i = 1 и j = 1? таким образом вы пропускаете первую строку и первый столбец
Вы поняли комментарий Теда? Проблема в том, что вы пытаетесь проверить элементы, у которых нет нижнего/верхнего/правого или верхнего элемента. Цикл только от индекса 1
до size()-2
проверяет только элементы, у которых есть 4 соседа
@RocketProcd Я думаю, вы должны были решить это с помощью карандаша и бумаги, прежде чем писать какой-либо код. Должно быть очевидно, что краевые элементы требуют специального рассмотрения. Если это случай «мне все равно, я напишу что угодно, чтобы получить большинство случаев, и оставлю это для того, чтобы кто-то добавил дополнительную логику», ну, StackOverflow не работает или не должен работать таким образом.
не может быть «стационарного элемента» в первой строке или первом столбце, когда «стационарный» означает, что он имеет top
и left
элемент
с другой стороны, неясно, обязательно ли стационарному элементу нужны 4 соседних элемента. Может ли быть неподвижный элемент в первой строке? Можете ли вы привести пример для этого случая?
если задать другой вопрос, имеет ли матрица с одним элементом {{1}}
стационарный элемент?
большое спасибо, теперь я понимаю, если кто-нибудь из вас ответит, я приму это
вам следует уточнить вопрос. Пока вопрос не ясен. Что вам нужно уточнить, так это то, что я спрашивал раньше: нужно ли стационарному элементу 4 соседа?
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 соседа
Проблема в том, что вы проверяете края матрицы и в позиции типа 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}};
это не вызовет исключения, вы должны посчитать все элементы и разделить на строки или что-то подобное, чтобы проверить, является ли матрица квадратной
@RocketProcd Да, это вызывает исключение. Вы установили try
/catch
?
извините, я не увидел цикл for, который проверяет каждую строку матрицы, я сейчас устал, поэтому я случайно пропустил его
@RocketProcd :-) Не беспокойтесь!
Разве вы не можете перейти от индекса
1
кsize()-2
(включительно)? Все равно нет смысла проверять координаты на краях, не так ли?