Eroare in C++. Cum as putea sa solutionez ?
#include
using namespace std;
ifstream fin("culoare.in");
ofstream fout("culoare.out");
const int di[]={-1, 0, 1, 0},
dj[]={ 0, 1, 0,-1};
int n , m, istart , jstart, a, culoare;
void Fill(int i ,int j ,int v, int abc)
{
// i,j - elementul curent, v - valoarea cu care facem Fill
if(i >= 1 && i <= n && j >= 1 && j <= m && A[i][j] == abc)
{ // in matrice, element liber si nemarcat
A[i][j] = v;
for(int k = 0 ; k < 4 ; k ++)
Fill(i + di[k] , j + dj[k], v, abc);
}
}
int main()
{
fin>>n>>m;
int A[n][25];
for(int i = 1 ; i <= n ;i ++)
for(int j = 1 ; j <= m ; j ++)
fin >> A[i][j];
fin >> istart >> jstart>> culoare;
a=A[istart][jstart];
Fill(istart, jstart, culoare, a);
for(int i =1 ; i <= n ;i ++, fout << "\n")
for(int j = 1; j <= m ; j ++)
fout << A[i][j] << " ";
return 0;
}
Răspunsuri la întrebare
► PROGRAM C++ :
#include <fstream>
using namespace std;
void fill(const unsigned i, const unsigned j, const unsigned culoare_noua, const unsigned culoare_veche, const unsigned n, const unsigned m, int** matrice)
{
const int di[] = { -1, 0, 1, 0 };
const int dj[] = { 0, 1, 0,-1 };
if (i >= 0 && i < n && j >= 0 && j <= m && matrice[i][j] == culoare_veche)
{
matrice[i][j] = culoare_noua;
for (int vecin = 0; vecin < 4; vecin++)
fill(i + di[vecin], j + dj[vecin], culoare_noua, culoare_veche, n, m, matrice);
}
}
//Functie pentru alocarea dinamica a memoriei
int** alocare_mem(int n, int m) {
//Alocare linii
int** A = new int* [n];
//Alocare coloane
for (int col = 0; col < m; col++)
A[col] = new int[m];
//Returnare matrice alocata dinamic
return A;
}
void dealocare(int** A, int n) {
//Dealocare fiecare linie
for (int col = 0; col < n; col++)
delete A[col];
//Dealocare fiecare coloana
delete A;
}
int main()
{
//Deschidere fisiere
ifstream fin("culoare.in");
ofstream fout("culoare.out");
//Citire dimensiuni matrice
int n, m;
fin >> n >> m;
//Alocare memorie matrice
int** matrice;
matrice = alocare_mem(n, m);
//Citire matrice
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
fin >> matrice[i][j];
//Citire coordonate start, culoare
unsigned istart, jstart, culoare;
fin >> istart >> jstart >> culoare;
//Compensare pentru inceperea de la 0
--istart;
--jstart;
//Inchidere fisier citire
fin.close();
//Umplere recursiva
fill(istart, jstart, culoare, matrice[istart][jstart], n, m, matrice);
//Afisare
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
fout << matrice[i][j] << " ";
fout << endl;
}
//Inchidere fisier scriere
fout.close();
//Dealocare matrice
dealocare(matrice, n);
return 0;
}
► Explicatie :
O variabila (fie aceasta o variabila simpla, vector, matrice, ins.tanta a unei clase, s.a.m.d. ) este vizibila doar in functia/scope in care este declarat.
Pentru ca matricea noastra sa fie vizibila in functia fill avem doua optiuni :
- Trimitem matricea ca parametru (adaugam int** matrice la lista de parametrii). Deoarece o matrice este un pointer catre un vector de vectori NU este necesar sa transmitem matricea prin referinta. Putem accesa si modifica elementele matricei direct.
- Declaram matricea global (nerecomandat)
- Ne folosim de avantajele programarii orientate pe obiect (recomandat cu tarie)
Pentru alocarea/eliberearea memoriei in mod dinamic in C++ avem operatorii new si delete.
Pentru alocarea memoriei trebuie sa alocam memorie pentru fiecare linie (liniile sunt vectori de numere intregi, deci int *), iar pentru fiecare astfel de linie trebuie sa alocam memorie pentru m variabile de tip int.
Dealocarea se face in ordine inversa (dealocam fiecare linie apoi dealocam matricea = vectorul de linii).
Gasesti pe net mai multe resurse privind alocarea dinamica in C++.
Sfaturi :
- Incercam sa evitam variabilele declarate global pe cat posibil. In proiecte mari acestea pot cauza probleme greu de diagnosticat, deci e indicat sa ne invatam sa le evitam pe cat putem de acum.
- Incercam sa declaram constant tot ce ar trebui sa fie constant.
- Inchidem fisierele in momentul in care nu mai avem nevoie de ele pentru a putea elibera resurse.
- Nu uitam sa eliberam memoria alocata dinamic.
- In mod normal se evita proiectarea functiilor cu mai mult de 3-4 parametrii, folosind concepte de programare orientata pe obiecte (presupun ca nu ai invatat, din acest motiv nici nu am folosit aici).
- Incercam sa pastram codul cat mai usor de citit, punem nume sugestiv variabilelor.
- Evitam functiile recursive, utilizam stive/cozi pentru a putea rezolva problema iterativ (nu am respectat sfatul asta aici, am vrut sa modific codul tau, dar pe viitor tine minte ca implementarile recursive "costa" mai mult decat implementarile iterative)
Ai test pe exemplu in atasament
{
int n; cin>>n;
string s;
getline (cin, s);
cout< return 0;
}
Tasta enter e echivalenta cu intalnirea caracterului new line.
Caracter gol = spatiu, caracter new line, caracter null, tab, etc.
Cand apelam getline apoi se intalneste caracterul new line (pe care cin nu l-a scos din buffer) si crede ca trebuie sa se opreasca. Copiaza stringul citit (de niciun caracter practic) in s si zice ca si-a terminat treaba.