Clasa a IX-a lecția 29
Lectie ( TEORIE )
Matrice
Matricele sînt asemănătoare cu vectorii, dar cu două dimensiuni (coordonate, poziții) în loc de una. Vectorii se mai numesc și tablouri unidimensionale, iar matricele se mai numesc și tablouri bidimensionale.
Declarare matrice
Matricele se declară similar cu vectorii, însă cu o dimensiune în plus:
int a[100][500];
Primul număr, 100 în cazul nostru, reprezintă numărul de linii al matricei a. Al doilea număr, 500 în exemplul de mai sus, reprezintă numărul de coloane al matricei a, sau numărul de elemente al fiecărei linii. O matrice poate fi privită ca un vector de vectori. În exemplul de mai sus a poate fi privită ca un vector de 100 de elemente. Fiecare element al acestui vector este, la rîndul lui, un alt vector, de 500 de elemente. Numărul total de elemente al matricei a este 100 x 500, adică 50000 de elemente întregi.
Citire matrice
Cum citim o matrice? Asemănător cu un vector, vom citi mai întîi numărul de linii și numărul de coloane, apoi elementele. Elementele se citesc, în general, de-a lungul liniilor, fiecare linie fiind citită ca un vector:
fscanf( fin, "%d%d", &n, &m );
for ( i = 0; i < n; i++ )
for ( j = 0; j < m; j++ )
fscanf( fin, "%d", &a[i][j] );
Scriere matrice
Scrierea este asemănătoare cu citirea, cu mențiunea să avem grijă să tipărim un '\n' la finalul fiecărei linii. Vom afisa linie cu linie, pentru fiecare linie, afisam elementele de pe acea linie si un sfarsit de linie.
for ( i = 0; i < n; i++ ) {
for ( j = 0; j < m; j++ )
fprintf( fout, "%d ", a[i][j] );
fprintf( fout, "\n" );
}
Parcurgerea elementelor unei matrice
In functie de cerintele problemei, parcurgerea elementelor matricei, in vederea prelucrarii acestora, poate fi facuta in mai multe modalitati. Cea mai intalnita metoda de a parcurge elementele unei matrice, este parcurgerea linie cu line. Sa presupunem ca ni se cere sa calculam suma elementelor tuturor elementelor. Iata allgoritmul:
s = 0;
for ( i = 0; i < n; i++ )
for ( j = 0; j < m; j++ )
s += a[i][j];
}
Un algoritm echivalent este acela de a parcurge matricea coloane cu coloana:
s = 0;
for ( j = 0; j < m; j++ )
for ( i = 0; i < n; i++ )
s += a[i][j];
}
Din punct de vedere al eficientei, credeti ca este vreo deosebire intre cei doi algoritmi?
Căutare element în matrice
i = j = 0;
while ( (i < n) && (a[i][j] != e) ) {
j++;
if ( j >= m ) {
j = 0;
i++;
}
}
if ( i == n )
//nu am gasit
Permutarea coloanelor spre stanga
Se dă o matrice cu n linii şi m coloane şi elemente numere naturale. Să se permute coloanele matricei circular spre stânga cu o poziție. PermCol
#include <stdio.h>
int a[100][100];
int main(){
int n, m, i, j, aux;
scanf ( "%d%d", &n, &m );
for ( i = 0; i < n; i++ )
for ( j = 0; j < m; j++ )
scanf ( "%d", &a[i][j] );
for ( i = 0; i < n; i++ ){
// permutam spre stanga linia i
aux = a[i][0]; // primul element de pe linia i il salvam in aux
for ( j = 0; j < m - 1; j++ ) // mutam spre dreapta toate celelalte elem de pe linie, incepand cu al doilea elem
a[i][j]= a[i][j+1];
a[i][m-1] = aux; // punem elementul salvat in aux pe ultima pozitie a liniei i
}
for ( i = 0 ; i < n ; i++ ){
for ( j = 0 ; j < m ; j++ )
printf ( "%d ", a[i][j] );
printf ( "\n" );
}
return 0;
}
LABORATOR
SumaLinii1
Gigel a găsit o matrice cu n linii și m coloane și elemente numere naturale. El își propune să determine, pentru fiecare linie, cea mai mică valoare care se poate obține adunând elementele de pe linie, cu excepția unuia.
#include <stdio.h>
int a[101][101];
int main(){
int n, m, s, c, l, max;
scanf ( "%d %d", &n, &m);
for ( l = 0 ; l < n ; l++ ){
s = 0;
max = a[l][0];
for ( c = 0 ; c < m ; c++ ){
scanf ( "%d", &a[l][c] );
s = s + a[l][c];
if ( a[l][c] > max ){
max = a[l][c];
}
}
s = s - max;
printf ( "%d ", s);
}
return 0;
}
MaxAp1
Se dă o matrice cu n linii şi m coloane şi elemente numere naturale. Să se determine elementul cu număr maxim de apariții în matrice. Dacă există mai multe elemente cu număr maxim de apariții se va afișa cel mai mare dintre ele.
#include <stdio.h>
#include <stdlib.h>
int v[1000000]; //vectorul de frecventa
int main(){
int n, m, i, j, x, maxap;
scanf( "%d%d", &m, &n );
for( i = 0; i < m; i++ ){
for( j = 0; j < n; j++ ){
scanf( "%d", &x );
v[x]++;
}
}
int val;
maxap = 0;
for( i = 0; i < 1000000; i++ )
if( v[i] >= maxap ){
maxap = v[i];
val = i;
}
printf("%d", val);
return 0;
}
OrdLin
Se dă o matrice cu n linii şi m coloane şi elemente numere naturale. Să se ordoneze liniile matricei crescător după suma elementelor.
#include <stdio.h>
#include <stdlib.h>
int a[101][101];
int main(){
int n, m, i, j, x, minim, poz;
// citim matricea si calculam suma pe fiecare linie, memorand sumele pe ultima coloana
scanf( "%d%d", &m, &n );
for( i = 0;i < m; i++ ){
a[i][n] = 0; // aici voi pune suma elementelor de pe linia i
for( j = 0; j < n; j++ ){
scanf( "%d", &a[i][j] );
a[i][n] += a[i][j];
}
}
// sortam liniile dupa elementele de pe coloana n cu metoda select sort
for( i = 0; i < m - 1; i++ ){
// determinam minimul si pozitia minimului pe coloana n, incepand de la linia i
minim = a[i][n]; poz = i;
for( j = i + 1; j < m; j++ )
if( a[j][n] < minim ){
minim = a[j][n];
poz = j;
}
// interschimb linia i cu linia poz ( inclusiv a[i][n] cu a[poz][n])
int aux;
for( x = 0; x <= n; x++ ){
aux = a[poz][x];
a[poz][x] = a[i][x];
a[i][x] = aux;
}
}
// afisam matricea
for( i = 0; i < m; i++ ){
for( j = 0; j < n; j++ )
printf( "%d ", a[i][j] );
printf( "\n" );
}
return 0;
}
MChenar
Se dă o matrice cu n linii şi m coloane şi elemente numere naturale. Să se determine mulțimea formată din elementele distincte ale chenarului matricei.
#include <stdio.h>
#include <stdlib.h>
int v[1000000]; //vectorul de frecventa
int main(){
int n, m, i, j, x;
scanf( "%d%d", &m, &n );
for( i = 0; i < m; i++ ){
for( j = 0; j < n; j++ ){
scanf( "%d", &x );
if ( i == 0 || j == 0 || i == m - 1 || j == n - 1 )
v[x]++;
}
}
for(i = 0; i < 1000000; i++ ){
if( v[i] > 0 )
printf("%d ", i );
}
return 0;
}
ColEgale
Se dă o matrice cu m linii şi n coloane şi elemente numere naturale cu cel mult 4 cifre fiecare. Să se determine coloanele matricei care au toate elementele egale cu aceeași valoare.
#include <stdio.h>
int a[50][50];
int main(){
int i, j, n, m, cnt;
scanf( "%d%d", &n, &m);
for( i = 0; i < n; i++ )
for( j = 0; j < m; j++ )
scanf( "%d", &a[i][j] );
cnt = 0;
for( j = 0; j < m; j++ ){
// cautam pe coloana j un element diferit de primul element al coloanei j
i = 1;
while( i < n && a[i][j] == a[0][j] )
i++;
// daca nu am gasit un element diferit printam valoarea comuna
if ( i == n ){
cnt ++;
printf("%d ", a[0][j]);
}
}
if (!cnt)
printf("nu exista");
return 0;
}
MCautare
Se dă o matrice cu n linii și m coloane și elemente numere naturale și k valori naturale. Determinați pentru fiecare dintre cele k valori dacă apare pe fiecare linie a matricei.
#include <stdio.h>
int a[100][100];
int main(){
int i, j, n, m, nr, x, cnt, k;
scanf( "%d%d", &m, &n );
for( i = 0; i < m; i++ )
for( j = 0; j < n; j++ )
scanf( "%d", &a[i][j] );
scanf( "%d", &nr );
for( k = 0; k < nr; k++ ){
scanf( "%d", &x );
// numaram pe cate linii apare x
cnt = 0;
for ( i = 0; i < m; i++ ){
j = 0;
while ( j < n && a[i][j] != x )
j++;
cnt = cnt + ( j < n );
}
// daca x apare pe toate liniile afisam DA altfel afisam NU
if ( cnt == m )
printf("DA\n");
else
printf("NU\n");
}
return 0;
}
_________________________________________________________________________________________________________________________
Citirea unei matrice de caractere fara sa se citeasca in prealabil dimensiunea ei
Sa se citeasca din fisierul "date.in" o matrice de caractere. Fiecare linie de caractere este pe cate un rand al fisierului, iar caracterele nu au spatii intre ele. D Vom citi prima linie a fisierului si vom determina numarul de elemente de pe aceasta, determinand astfel numarul de coloane ale matricei n. Apoi vom citi urmatoarele linii pana la intalnirea sfarsitului de fisier.
// Sol 9 C
#include <stdio.h>
char a[100][100];
int main() {
FILE *fin, *fout;
int n, m, l, c;
char ch;
fin = fopen( "date.in", "r" );
// citim intii prima linie pina la '\n', pentru a-l afla pe n=nr. de coloane
n = 0;
ch = fgetc( fin );
while ( ch != '\n' ) {
a[0][n] = ch;
n++;
ch = fgetc( fin );
}
// citim linie cu linie pana ajungem la o linie goala sau la finalul fisierului(EOF)
ch = fgetc( fin );
m = 1; // nr. de linii
while ( ch != '\n' && ch != EOF ) {
// Fisierul nu s-a terminat, citim urmatoarea linie:
for ( c = 0; c < n; c++ ) {
a[m][c] = ch;
ch = fgetc( fin );
}
m++;
ch = fgetc( fin );
}
// Afisam matricea
fout = fopen( "date.out", "w" );
for ( l = 0; l < m; l++ ) {
for ( c = 0; c < n; c++ )
fputc( a[l][c], fout );
fputc( '\n', fout );
}
fclose( fout );
return 0;
}
O implementare similara a solutiei de mai sus presupune citirea tuturor caracterelor pana la sfarsit de fisier. Vom numara elementele pana la intalnirea primului sfarsit de linie, determinand astfel numarul de coloane si vom numara '\n'-rile determinand astfel numarul de linii.
//Sol 9I
#include <stdio.h>
char a[100][100];
int main() {
FILE *fin, *fout;
int n, m, l, c,i;
char ch;
fin = fopen( "date.in", "r" );
// citim intii prima linie pina la '\n', pentru a-l afla pe n=nr. de coloane
i = m = n = 0;//m = nr de linii, m = linii de coloane
ch = fgetc( fin );
while (ch != EOF ) {
if(ch == '\n'){
if(m == 0)
n = i;
m++;
i = 0;
}
else{
a[m][i] = ch;
i++;
}
ch = fgetc(fin);
}
// Afisam matricea
fout = fopen( "date.out", "w" );
for ( l = 0; l < m; l++ ) {
for ( c = 0; c < n; c++ )
fputc( a[l][c], fout );
fputc( '\n', fout );
}
fclose( fout );
return 0;
}
O alta solutie ar fi sa retinem toate elementele intr-un vector, determinand numarul de linii in functie de numarul de '\n' uri, iar numarul de coloane il putem determina pe baza numarului de linii si al numarului total de elemente trasnferate in vector. La final vom afisa elementele vectorului sub forma unei matrice, tiparind cate n elemente pe fiecare rand.
#include <stdio.h>
char a[100*100];
int main() {
FILE *fin, *fout;
int n, m, l, c, j;
char ch;
fin = fopen( "date.in", "r" );
// Construim un vector cu toate elementele matricei
m = j = 0; //m = nr de linii, j = numarul de elemente citite
ch = fgetc( fin );
while (ch != EOF ) {
if( ch == '\n' )
m++;
else
a[j++] = ch;
ch = fgetc(fin);
}
n = j / m; // n = nr de coloane = nr de elemente citite / nr de linii
// Afisam matricea
fout = fopen( "date.out", "w" );
for ( l = 0; l < m; l++ ) {
for ( c = 0; c < n; c++ )
fputc( a[l*n+c], fout );
fputc( '\n', fout );
}
fclose( fout );
return 0;
}
Sarcina Laborator:
- Cititi o matrice de numere naturale fara sa se cunoasca dimensiunea acestea
- Cititi o matrice de numere intregi fara sa se cunoasca dimensiunea acesteia
Tema
Tema Teorie
Rezolvati urmatoarele probleme de pe pbinfo.ro
SumaPare2
Se dă o matrice cu n linii şi m coloane şi elemente numere naturale. Determinați suma valorilor pare din matrice.
SumaLinii
Se dă o matrice cu n linii și m coloane și elemente numere naturale. Să se determine suma elementelor de pe fiecare linie.
NrPrime
Se dă o matrice cu n linii și m coloane și elemente numere naturale. Să se determine câte dintre elementele situate pe linii cu indici pari sunt prime.
SumaPare3
Se dă o matrice cu n linii şi m coloane şi elemente numere naturale. Determinați suma valorilor pare distincte din matrice. Dacă o valoare pară apare în matrice de mai multe ori, se va aduna o singură dată.
MaxAp
Se dă o matrice cu n linii şi m coloane şi elemente numere naturale. Să se determine elementul cu număr maxim de apariții în matrice. Dacă există mai multe elemente cu număr maxim de apariții se vor afișa toate, în ordine crescătoare.
Tema Laborator pbinfo
Max2Ap
Se dă o matrice cu n linii şi m coloane şi elemente numere naturale. Să se determine cea mai mare valoare care apare în matrice de cel puțin două ori.
CntLinii
Se dă o matrice cu n linii şi m coloane şi elemente numere naturale. Să se determine câte linii ale matricei au toate elementele egale.
CntColoane
Se dă o matrice cu n linii şi m coloane şi elemente numere naturale. Să se determine câte coloane ale matricei au elementele distincte două câte două.
OrdCol
Se dă o matrice cu n linii şi m coloane şi elemente numere naturale. Să se ordoneze coloanele matricei astfel încât elementele de pe prima linie să fie ordonate crescător.
SumElPare
Se dă o matrice cu n linii și m coloane și elemente numere naturale. Să se determine indicele liniei pentru care suma elementelor pare este maximă.
NrPare
Se dă o matrice cu n linii şi m coloane şi elemente numere naturale. Determinați indicele liniei care conține număr maxim de elemente pare. Dacă există mai multe linii cu număr maxim de elemente pare, se vor afișa toți indicii, în ordine crescătoare.
Matrice7
Se consideră o matrice cu n linii şi m coloane şi elemente numere naturale. Să se modifice matricea în felul următor: toate elementele egale cu valoarea maximă din matrice se înlocuiesc cu valoarea minimă de pe coloana lor.