Inundación No funciona (c)

Tengo algunos problemas con mi función de inundación que no funciona. El propósito de esta asignación es ver si P y C están conectados dentro del arreglo. En la función de inundación, no parece estar cambiando '_' a 'P'

Entrada de muestra

5 
1 2
PC
2 1
P
C
2 2
P#
#C
2 2
P_
C_
8 7
__P____
####_##
_____#_
_____#C
##_###_
_____#_
___#_#_
___#___
5 7
__P____
####_##
_____#_
_____#C
##_###_

Código

#include <stdio.h>
#define MAXC 10
#define MAXR 10

void floodfill(char map[][MAXC+1], int i, int j, int r, int c);
int checklocation(char map[][MAXC+1], int i, int j, int r, int c);

int main() {


    FILE* ifp = fopen("bunnies.in", "r");

    int numcases, loop;
    fscanf(ifp, "%d", &numcases);


    for (loop=0; loop<numcases; loop++) {

        int r, c, i=0, j=0;


        fscanf(ifp, "%d%d", &r, &c);
        //printf("\nRows = %d Cols = %d\n", r,c); //debug comment out
        char map[r][c];

        //Read in input
        for(i=0; i<r; i++) {

            map[i][j] = fgetc(ifp);

                for (j=0; j<c; j++) {
                    map[i][j] = fgetc(ifp);
                    //printf("%c", map[i][j]); //test input read comment out
                }
           // printf("\n"); //test input read comment out
        }

        int broken = 0; //to keep track if floodfill already occured

        for (i=0; i<r; i++) {

           // if (broken == 1)
            //    continue;

            for (j=0; j<c; j++) {

               // if (broken == 1)
                //    continue;

                //the whole loop only looks for P then floodfills
                if(map[i][j] == 'P') {
                    floodfill(map, i, j, r, c);
                 //   broken = 1;


                }

               // printf("%c", map[i][j]); //test floodfill, comment out later

            }

            //printf("\n"); //test floodfill, comment out later

        }

        int found = 0;

        //searches for C, calls checklocation when found
        for (i=0; i<r; i++) {
            for(j=0; j<c; j++) {
                if (map[i][j] == 'C')
                    found = checklocation(map, i,j, r, c);
            }
        }

        if (found == 1)
            printf("yes\n");
        else
            printf("no\n");

    }

fclose(ifp);
return 0;

}


//Pass map pointer, position in array i,j and row/column numbers
void floodfill(char map[][MAXC+1], int i, int j, int r, int c) {

//printf("looking at: [%d][%d]\n", i,j); //debug comment out later

//'base case' that deals with out of bounds
if (i<0 || j<0 || i>=r || j>=c)
    return;

if (map[i][j] != '_')
    return;

if (map[i][j] == '_')
    map[i][j] = 'P';



floodfill(map, r, c, i, j+1); //check right
floodfill(map, r, c, i, j-1); //check left
floodfill(map, r, c, i+1, j); //check below
floodfill(map, r, c, i-1, j); //check above

//printf("%c", map[i][j]);

}

//Same parameters as floodfill
int checklocation(char map[][MAXC+1], int i, int j, int r, int c) {

//these if statements check for p in each location around and
//makes sure the coordinate is in bounds
if (map[i-1][j] == 'P' && ((i>=0 && i < r) && (j>=0 && j < c)))
    return 1;

else if (map[i+1][j] == 'P' && ((i>=0 && i < r) && (j>=0 && j < c)))
    return 1;

else if (map[i][j+1] == 'P' && ((i>=0 && i < r) && (j>=0 && j < c)))
    return 1;

else if (map[i][j-1] == 'P' && ((i>=0 && i < r) && (j>=0 && j < c)))
    return 1;

else
    return 0;

}

preguntado el 12 de junio de 12 a las 16:06

Aprenderás mucho más si descubres lo que está pasando por ti mismo. Para hacer esto, agregue printf() para generar una salida de seguimiento en lugares importantes (como los argumentos en cada llamada de función). Mejor aún, aprenda a usar su depurador. -

Un problema: en checklocation, las sentencias if no tienen sentido. Traza mentalmente el código con i = j = 0; y mira lo que pasa. -

1 Respuestas

Tus floodfill() parece estar roto:

cuando lo llamas en la ubicación de P, el siguiente cheque

if (map[i][j] != '_')
    return;

regresará inmediatamente sin hacer nada (como map[i][j] is P ahi no _)

Tratar:

if (map[i][j] == '_') {
  map[i][j] = 'P';

  floodfill(map, r, c, i, j+1); //check right
  floodfill(map, r, c, i, j-1); //check left
  floodfill(map, r, c, i+1, j); //check below
  floodfill(map, r, c, i-1, j); //check above
}

esto cambiará la posición actual y solo llamará al floodfill circundante si es necesario

Tenga en cuenta que esto aún omitirá la P inicial, que puede corregir configurando map[i][j] a _ justo antes de llamar floodfill() del main()

Además, parece que estás leyendo demasiado de la entrada:

map[i][j] = fgetc(ifp);
for (j=0; j<c; j++) {
  map[i][j] = fgetc(ifp);
  ...

leerá un carácter para el actual i y lea uno para cada j de nuevo. Si está leyendo la nueva línea en el primer caso, no necesita almacenarla en map[i,j], especialmente porque hacerlo alterará el mapa después del primer bucle j (que ahora tiene el valor c)

Además, en checklocation(), debe verificar los casos límite antes de verificar el elemento en map (como Gene insinuó en los comentarios), de lo contrario, su verificación de límites no tiene valor.

Respondido el 12 de junio de 12 a las 17:06

Pero el valor inicial de map[i][j] cuando llama a la función floodfill es P, por lo que nunca iniciará la parte if('_'). Ahí es donde estoy atascado - Ryan

@ usuario1451642 - cierto. Colocar map[i][j] a '_' justo antes de llamar floodfill() a partir de su main() función - Attila

Ok, tengo mi entrada de lectura como for (i=0; i<r; i++){ fscanf(ifp, "%s", map[i]); y aquí está mi llamada de inundación if(map[i][j] == 'P') { map[i][j] = '_'; floodfill(map, i, j, r, c); - Ryan

@ user1451642: ¿su problema se resolvió ahora o todavía tiene problemas? - Attila

@ user1451642: en caso de que aún tenga problemas, aquí hay un ejemplo práctico: ideone.com. Tenga en cuenta que he cambiado las llamadas de lectura de archivos a llamadas de lectura estándar. - Attila

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.