#c #recursion #blob
#c #рекурсия #большой двоичный объект
Вопрос:
Сегодня у нас была задача, в которой нам нужно было найти все пиксели, которые были связаны друг с другом на картинке. Изображение просто зеленое = 1, без цвета = 0 и может быть представлено в виде массива:
int grid[5][5] = {
{1, 1, 0, 0, 0},
{0, 1, 1, 0, 0},
{0, 0, 1, 0, 1},
{1, 0, 0, 0, 1},
{0, 1, 0, 1, 1},
};
Мы сидели 3 часа в моей группе и пытались решить эту проблему (первая лекция о рекурсии), но мы просто не можем заставить ее работать. Проблема, похоже, в том, что функции каким-то образом принимают нахождение вне сетки. Любой, кто, вот код:
#include <stdio.h>
#include <string.h>
//Prototype
int blob_count(int y, int x, int gridCopy[][5], int sum);
int blob_count(int y, int x, int gridCopy[][5], int sum){
//Local vars
int posX, posY;
printf("nnX: %d - Y: %dnposX: %d - posY: %dnSum: %d", x, y, posX, posY, sum);
printf("nn{%d - %d - %d - %d - %d}n{%d - %d - %d - %d - %d}n{%d - %d - %d - %d - %d}n{%d - %d - %d - %d - %d}n{%d - %d - %d - %d - %d}n",
gridCopy[0][0],
gridCopy[0][1],
gridCopy[0][2],
gridCopy[0][3],
gridCopy[0][4],
gridCopy[1][0],
gridCopy[1][1],
gridCopy[1][2],
gridCopy[1][3],
gridCopy[1][4],
gridCopy[2][0],
gridCopy[2][1],
gridCopy[2][2],
gridCopy[2][3],
gridCopy[2][4],
gridCopy[3][0],
gridCopy[3][1],
gridCopy[3][2],
gridCopy[3][3],
gridCopy[3][4],
gridCopy[4][0],
gridCopy[4][1],
gridCopy[4][2],
gridCopy[4][3],
gridCopy[4][4]);
//Find the position 1 behind and 1 above the starting point, and start the loop there
for(posX = -1;posX <=1; posX ){
for(posY = -1; posY <= 1; posY ){
if((y posY) >= 0 amp;amp; (x posX) >= 0){
if((y posY) <= 5 amp;amp; (x posX) <= 5){
if(gridCopy[posY y][posX x] == 1){
//Set the starting point to 0 (so it wont get calculated again)
gridCopy[posY y][posX x] = 0;
y = posY y;
x = posX x;
sum ;
blob_count(y, x, gridCopy, sum);
}
}
}
}
}
return sum;
}
int main (void)
{
int grid[5][5] = {
{1, 1, 0, 0, 0},
{0, 1, 1, 0, 0},
{0, 0, 1, 0, 1},
{1, 0, 0, 0, 1},
{0, 1, 0, 1, 1},
};
//Create a manipulateable grid
int gridCopy[5][5];
memcpy(gridCopy, grid, 5*5*sizeof(int));
//Start Positions
int start_x = 0;
int start_y = 3;
//If the starting point selected, is not 0, initiate the function:
if(grid[start_y][start_x] != 0){
printf("nSum: %d", blob_count(start_y ,start_x, gridCopy, 0));
}
}
Редактировать:
Я обновил приведенный выше код, и теперь у меня новая проблема, он получает правильную сумму (количество пикселей в сочетании друг с другом), однако, когда я распечатываю сумму (в main();), она говорит 1, почему она не переносится из рекурсивной функциик основной функции?
Комментарии:
1. Моя проблема заключалась бы в том, что, похоже, она выходит за пределы сетки, хотя это не должно быть разрешено, я не вижу, как я могу приблизиться, когда я не уверен, в чем именно проблема, кроме того, что она этого не делает.
Ответ №1:
Вы смотрите на всех соседей текущего пикселя:
for(posX = -1;posX<=1;posX ){
for(posY = -1; posY<= 1;posY ){
И вы проверяете, что координаты положительные:
if((y posY) >= 0 amp;amp; (x posX) >= 0){
Но вы не проверяете, что координаты не переполняются:
if((y posY) < 5 amp;amp; (x posX) < 5) {
И вместо этого получить доступ к неопределенным данным за пределами сетки:
if(gridCopy[posY y][posX x] == 1){
Вероятно, это все равно не сработает, но, поскольку это домашнее задание, я просто дам вам несколько советов: вы игнорируете возвращаемое значение рекурсивного вызова (не делайте этого) и не инициализируете sum
(включите предупреждения компилятора, чтобы получать уведомления об этом).). Вы также не копируете всю сетку целиком: memcpy(gridCopy, grid, 5*5);
копирует 25 байт, а не 25 целых. Используйте memcpy(gridCopy, grid, 5 * 5 * sizeof(int));
вместо этого.
Комментарии:
1. Спасибо, я изучу эти вещи. Однако это не домашнее задание. Наши лекции состоят из 2 частей: 1 часть лекции и 1 часть групповой работы. Групповые задачи используются только в этих уроках, поэтому я не буду разбираться, как это сделать, если я не исследую себя, и мне не нужно это включать.