Gestiunea Submatricilor

Vasilică vă roagă să implementați o serie de funcții în cadrul unui fișier header care va trebui intitulat functii.h. Funcțiile ce trebuie implementate sunt următoarele:

  • char** initMatrix(char *filename, int* nlinii, int* ncoloane);
  • char** getSubMatrix(char **A, int l, int c, int *nlinii, int *ncoloane);
  • char** getXorSubMatrix(char **A, int *nlinii, int *ncoloane);
  • void deleteMatrix(char **A);
  • int isValid(char **A);
  • void finishedTest();
char** initMatrix(char *filename, int* nlinii, int* ncoloane)

Această funcție primește ca parametri un nume de fișier și doi pointeri la 2 variabile de tip int. Fișierul are următorul format:

  • pe prima linie se află numerele M și N
  • urmează apoi M linii ce conțin fiecare câte N numere (separate prin spații), descriind o matrice
  • fiecare număr este între 0 și 100, astfel ca tipul elementelor matricii trebuie sa fie char

Funcția trebuie să întoarcă un pointer către o matrice alocată dinamic ce conține numerele din fișier (matricea are M linii și N coloane). De asemenea, intern, va trebui să păstrați o referință la această matrice (și, eventual, alte informații) — veți vedea în continuare de ce. La locațiile reprezentate de pointerii nlinii și ncoloane veți scrie valorile M (numărul de linii) și, respectiv N (numărul de coloane).

char** getSubMatrix(char **A, int l, int c, int *nlinii, int *ncoloane)

Această funcție primește ca parametru un pointer către o matrice creată anterior (printr-un apel al funcțiilor initMatrix, getSubMatrix sau getXorSubMatrix), 2 valori întregi l și c, și 2 pointeri la 2 variabile de tip int. Această funcție va crea (și va intoarce ca rezultat) o submatrice a matricii A, care conține toate liniile matricii începând de la linia l și toate coloanele începând de la coloana c (deci colțul stânga-sus al submatricii este (l,c)). Matricea trebuie creată în așa fel încât elementele submatricii să se suprapună în memorie peste elementele corespunzătoare ale matricii A. Mai exact, trebuie ca dacă modificăm un element din submatrice să se modifice automat și elementul corespunzător din matricea A. Submatricea astfel creată se numește fiu al matricii A.

În locațiile de memorie ale pointerilor nlinii și ncoloane veți scrie numărul de linii și, respectiv, de coloane, ale submatricii create.

În caz că pointerul către matricea A nu corespunde unei matrici create anterior, funcția va întoarce NULL (și va scrie valorile 0 la cele 2 locații de memorie date ca parametru).

char** getXorSubMatrix(char **A, int *nlinii, int *ncoloane)

Această funcție primește ca parametru un pointer catre o matrice creată anterior (printr-un apel al funcțiilor initMatrix, getSubMatrix sau getXorSubMatrix) și 2 pointeri la 2 variabile de tip int. Funcția va crea și va întoarce ca rezultat o matrice cu același număr de linii și coloane ca și matricea A. Să presupunem că matricea rezultat se va numi B.

Matricea A are structura:

A[0][0] A[0][1] ... A[0][număr_coloane(A)-1]
A[1][0] A[1][1] ... A[1][număr_coloane(A)-1]

.................................................

A[număr_linii(A)-1][0] A[număr_linii(A)-1][1] ... A[număr_linii(A)-1][număr_coloane(A)-1]

Elementul B[i][j] va fi egal cu xor-ul tuturor valorilor A[p][q] cu 0<=p<=i și 0<=q<=j (practic, este xor-ul tuturor elementelor din submatricea matricii A care are colțul stânga-sus la (0,0) și colțul dreapta-jos la (i,j)).

Matricea întoarsă nu se consideră fiu al matricii A.

În caz că pointerul către matricea A nu corespunde unei matrici create anterior, funcția va întoarce NULL (și va scrie valorile 0 la cele 2 locații de memorie date ca parametru).

void deleteMatrix(char **A)

Această funcție va invalida matricea A (A este un pointer către o matrice creată anterior printr-un apel al funcțiilor initMatrix, getSubMatrix sau getXorSubMatrix). Invalidarea nu presupune neaparat eliberarea memoriei matricii. O dată cu invalidarea unei matrici, trebuie invalidate în mod automat toate matricile care sunt fii ai lui A, sau fii ai fiiilor lui A ș.a.m.d. (practic, orice matrice care este un descendent al matricii A trebuie invalidată în urma acestui apel).

În caz ca pointerul către matricea A nu corespunde unei matrici create anterior, funcția nu va efectua nicio acțiune.

int isValid(char **A)

Această funcție primește ca parametru un pointer către o matrice creată anterior (printr-un apel al funcțiilor initMatrix, getSubMatrix sau getXorSubMatrix) și întoarce valoarea 1 dacă matricea respectiva este validă, respectiv 0 dacă a fost invalidată în prealabil (sau dacă pointerul nu corespunde unei matrici create anterior).

void finishedTest()

Această funcție anuntă sfarșitul unui test. În cadrul acestei funcții trebuie eliberate toate locațiile de memorie alocate dinamic (și care nu au fost deja eliberate) ; eventual, se poate amâna eliberarea tuturor locațiilor de memorie alocate dinamic până la apelul acestei funcții.

Indicații

În cadrul fișierului header puteți declara variabile globale care pot fi accesate de funcțiile definite în header. În felul acesta puteți menține referințe la matricile și submatricile create, precum și informații despre ele (de ex., număr de linii, coloane, dacă este validă sau nu, numărul de fii, vector de fii, etc.). Se recomandă folosirea unei structuri pentru a reține toate aceste informații.

Autor: Mugurel Ionuț Andreica

Data: 07.01. 2010