Fișierul matrice.in conține o matrice cu n linii și m coloane (n<=20, m<=20) elemente de tip întreg. Elaborați un program prin intermediul căruia la ecran se vor afișa elementele de pe diagonala principală a matricei sortate crescător și descrescător utilizînd metoda prin inserție.
In limbajul C.
Răspunsuri la întrebare
Răspuns:
#include <stdio.h>
#include <stdlib.h>
// Funcția crează o matrice de N linii și M coloane
static int** creare_matrice(int nr_linii, int nr_coloane) {
// alocăm un vector de N int*
int** matrice = (int**)malloc(sizeof(int*) * (size_t)nr_linii);
// dacă malloc n-a alocat memorie cu succes ieșim din program
if (matrice == NULL) {
exit(EXIT_FAILURE);
}
for (int i = 0; i < nr_linii; ++i) {
// pentru fiecare int* alocăm un vector de M întregi
matrice[i] = (int*)malloc(sizeof(int) * (size_t)nr_coloane);
// din nou, dacă malloc n-a putut să aloce memorie cu succes, ieșim din program
if (matrice[i] == NULL) {
exit(EXIT_FAILURE);
}
}
// la final returnăm adresa matricii
return matrice;
}
// Funcția afișează matricea de N linii și M coloane
static void afiseaza_matrice(int** matrice, int nr_linii, int nr_col) {
printf("Matricea este:\n");
for (int i = 0; i < nr_linii; ++i) {
for (int j = 0; j < nr_col; ++j) {
printf("%d ", matrice[i][j]);
}
printf("\n");
}
}
// Funcția eliberează memoria alocată de către „creaza_matrice(...)”
static void dealoca_matricea(int** matrice, int nr_linii) {
// eliberăm memoria pentru fiecare vector de întregi
for (int i = 0; i < nr_linii; ++i) {
free(matrice[i]);
}
// eliberăm memoria pentru vectorul de int*
free(matrice);
}
// Sortează vectorul prin inserție
// crescător = 0 -> sortare descrescătoare
// crescător = 1 -> sortare crescătoare
static void sortare_prin_insertie(int* vector_nr, int dim_vector, int crescator) {
int i, val_curenta, j;
for (i = 1; i < dim_vector; ++i) {
// salvăm valoarea curentă într-o variabilă temporară
val_curenta = vector_nr[i];
/*j va arăta întotdeauna cu un element în spatele valorii curente
de exemplu dacă avem vector_nr = {2, 1, 3, 4}
vector_nr[i] = 2 și vector_nr[j] = 1*/
j = i - 1;
// dacă sortăm crescător
if (crescator == 1) {
// cât timp nu suntem la începutul vectorului și dacă valoarea precedentă este mai mare decât valoarea curentă
while (j >= 0 && vector_nr[j] > val_curenta) {
/* shiftăm valoarea precedentă la cea de după ea
de exemplu dacă avem vector_nr = {2, 1, 3, 4}
vector_nr[j + 1](1) devine vector_nr[j](2)
deci vector_nr va deveni {2, 2, 3, 4}*/
vector_nr[j + 1] = vector_nr[j];
j = j - 1;
}
// Altfel dacă vrem să sortăm descrescător principiul este cam același
} else {
while (j >= 0 && vector_nr[j] < val_curenta) {
vector_nr[j + 1] = vector_nr[j];
j = j - 1;
}
}
/* și la final inserăm unde trebuie val curentă iar vec_numere va fi
{1, 2, 3, 4}*/
vector_nr[j + 1] = val_curenta;
}
}
// Funcția crează un vector cu elem. de pe diag. princ. și le afișează sortate crescător și descrescător
static void afiseaza_elem_diag_princ(int** matrice, int nr_linii) {
// Alocăm un vector de N întregi
int* vector_nr = (int*)malloc(sizeof(int) * (size_t)nr_linii);
// Dacă malloc n-a putut aloca memorie cu succes ieșim din program
if (vector_nr == NULL) {
exit(EXIT_FAILURE);
}
// Copiem elementele de pe diagonala principală în vector
for (int i = 0; i < nr_linii; ++i) {
vector_nr[i] = matrice[i][i];
}
// Prima dată le sortăm crescător
sortare_prin_insertie(vector_nr, nr_linii, 1);
// Iar mai apoi afișăm întregii din vector
printf("Elementele de pe diagonala principala sortate crescator sunt >> ");
for (int i = 0; i < nr_linii; ++i) {
printf("%d ", vector_nr[i]);
}
printf("\n");
// După sortăm descrescător
sortare_prin_insertie(vector_nr, nr_linii, 0);
// Și din nou afișăm întregii din vector
printf("Elementele de pe diagonala principala sortate descrescator sunt >> ");
for (int i = 0; i < nr_linii; ++i) {
printf("%d ", vector_nr[i]);
}
printf("\n");
// La final eliberăm memoria alocată cu malloc
free(vector_nr);
}
int main() {
FILE* fisier;
int N, M, **matrice;
// Dacă fișierul n-a putut fi deschis cu succes ieșim din program
if ((fisier = fopen("matrice.in", "r")) == NULL) {
perror("Eroare");
exit(EXIT_FAILURE);
}
// Altfel de pe primul rând citim numărul de linii și de coloane
fscanf(fisier, "%d%d", &N, &M);
printf("Numar linii >> %d, numar coloane >> %d\n", N, M);
// Creăm matricea de N linii și M coloane
matrice = creare_matrice(N, M);
// De pe cele N linii vom citi cele M numere și le vom salva în matrice
for (int i = 0; i < N; ++i) {
for (int j = 0; j < M; ++j) {
fscanf(fisier, "%d", &matrice[i][j]);
}
}
// Dacă fișierul n-a putut fi închis cu succes, ieșim din program
if ((fclose(fisier)) == EOF) {
exit(EXIT_FAILURE);
}
// Dacă până aici nu s-a produs nicio eroare afișăm matricea
afiseaza_matrice(matrice, N, M);
// Afișăm elementele de pe diagonală sortate crescător și descrescător
afiseaza_elem_diag_princ(matrice, N);
// Și la final eliberăm memoria
dealoca_matricea(matrice, N);
return 0;
}
Îți pun aici și conținutul fișierului „matrice.in”
3 3
22 6 3
4 19 100
123 5 3