Inundación No funciona (c)
Frecuentes
Visto 618 veces
0
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;
}
1 Respuestas
0
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 c flood-fill or haz tu propia pregunta.
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. - Gene
Un problema: en
checklocation
, las sentencias if no tienen sentido. Traza mentalmente el código coni = j = 0;
y mira lo que pasa. - Gene