2012-06-12 4 views
0

У меня возникли проблемы с моей функцией наводнения, которая не работает. Цель этого задания - проверить, связаны ли P и C внутри массива. В функции заливка оно не кажется, изменяя '_' на 'Р'Floodfill Не работает (c)

ввода образца

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

Код

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

} 
+0

Вы узнаете гораздо больше, если вы поймете, что происходит с вами. Для этого добавьте printf() для генерации вывода трассировки в важных местах (например, аргументы при каждом вызове функции). Еще лучше узнать, как использовать отладчик. – Gene

+0

Одна проблема: в 'checklocation', операторы if не имеют смысла. Мысленно проследим код с помощью 'i = j = 0;' и посмотрим, что произойдет. – Gene

ответ

0

Ваш floodfill(), кажется, сломана:

, когда вы позвоните по телефону P, следующая проверка:

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

немедленно возвратится, ничего не делая (как map[i][j] является P там, не _)

Try:

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 
} 

это изменит текущую позицию и вызывать окружающую заливку при необходимости

Обратите внимание, что это все равно пропустит начальное значение P, которое вы можете исправить, установив map[i][j] в _ прямо перед вызовом floodfill() от main()

Кроме того, вы, кажется, читает слишком много от входа:

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

будет считывать символ для текущего i и читать по одному для каждого j снова. Если вы читаете новую строку в первом случае, вам не нужно хранить его в map[i,j], тем более, что делать это будет изменить карту после первого цикла через j (который теперь имеет значение c)

Кроме того, в checklocation() вам нужно проверить граничные случаи, прежде чем вы проверите элемент в map (как Джин намекнул на комментарии), в противном случае ваша проверка границ бесполезна.

+0

Но начальное значение карты [i] [j], когда оно вызывает функцию заливки, равно P, поэтому он никогда не запустит часть if ('_'). Вот где я застрял – Ryan

+0

@ user1451642 - true. Установите 'map [i] [j]' на '' _'' перед тем, как вы вызовете 'floodfill()' из вашей функции 'main()' – Attila

+0

. Ok У меня есть мой прочитанный ввод как 'for (i = 0; i Ryan

Смежные вопросы