Table of Contents

Laboratorul 04 - Tablouri

Breviar

În acest laborator veţi învăţa să:

Declararea vectorilor

Vectorii (numiţi mai corect, array-uri) se declară ca orice altă variabilă, după tiparul

tip-dată nume-variabila;

cu menţiunea că după numele variabilei, vom specifica între paranteze pătrate numărul de elemente.

Array-urile în două dimensiuni se numesc în mod uzual matrice, şi se declară în mod similar, cu menţiunea că vom avea în ordine câte un număr de elemente înconjurat de paranteze pătrate pentru fiecare dimensiune în parte.

În definirea tablourilor, numărul de dimensiuni nu este limitat decât de raţiuni practice.

De exemplu, vom declara un vector de numere intregi, o matrice patratică de numere reale, şi un cub de caractere astfel:

int integer_vector[100];
float floating_point_matrix[100][100];
char character_cube[100][100][100];

Dimensiunile tablourilor

În standardul ANSI C, nu putem specifica dimensiunile vectorilor decât prin constante. Nu putem declara, de exemplu:

int n = 100;
int integer_variable_vector[n]; /* GRESIT! */

Elementele array-urilor sunt numerotate în mod obligatoriu începând de la 0.

ATENŢIE! Numărul dintre paranteze pătrate din cadrul declaraţiei reprezintă numărul de elemente din vector, NU indicele maxim. Din cauză că elementele sunt numerotate începând de la 0, elementul cu indicele maxim din vector este mereu cu 1 mai mic decât dimensiunea vectorului!

Dacă veţi încerca să accesaţi elemente din vector cu indici negativi sau mai mari sau egali cu dimensiunea vectorului, programul vostru se va comporta imprevizibil!

Accesarea elementelor dintr-un tablou se face prin intermediul parantezelor pătrate. De exemplu:

v[0]; /* Primul element din array. */
a[5][6]; /* Elementul din matrice aflat pe linia 5 şi coloana 6 (numerotarea începe de la 0) */
c[1][0][1]; /* Elementul din cub aflat la coordonatele (1, 0, 1) */

Iterarea tablourilor

Una dintre cele mai frecvente operaţii cu tablouri o reprezintă iterarea elementelor din acestea. În mod uzual, iterarea elementelor din tablouri se face în C cu ajutorul unei bucle de tip for (dar se poate folosi, evident, oricare dintre instrucţiunile repetitive). De exemplu:

int i, j, v[1000];
float a[10][10];
 
/* Parcurgem elementele vectorului v şi le inversăm semnul */
for (i = 0; i < 1000; i++) {
v[i] = -v[i];
}
 
/* Umplem matricea a cu 0-uri */
for (i = 0; i < 10; i++) {
for (j = 0; j < 10; j++) {
a[i][j] = 0;
}
}

O altă observaţie importantă este că valorile folosite pe post de indici într-un tablou nu pot fi decât valori (sau variabile) întregi. Nu este permisă indexarea unui tablou folosind variabile de tip float sau double!

Iniţializarea tablourilor

Tablourile pot fi iniţializate în momentul declarării. Specificarea valorilor din tablouri se face listând în ordine, valorile elementelor, începând cu elementul de pe poziţia 0. De exemplu:

int bancnote[6] = { 1, 5, 10, 50, 100, 200 };
float coeficienţi[10] = { 1.0, 2.0 }; // Restul valorilor se vor completa automat cu zerouri.
int v[1000] = { 0 }; // Iniţializăm vectorul cu 0 în momentul declarării.
// Ultimele 999 de zerouri se pun automat.

Atunci când în lista de valori sunt specificate mai puţine valori decât dimensiunea vectorului, vectorul se completează cu zerouri! O metoda convenabilă de a iniţializa un vector local unei funcţii cu valoarea 0 poate fi iniţializarea cu o singură valoare de 0, restul completându-se automat.

Iniţializarea se poate face şi atunci când este vorba de tablouri în mai multe dimensiuni. Trebuie de ţinut în acest caz minte că o matrice este un vector de vectori, un cub este un vector de vectori de vectori, s.a.m.d.

În cazul iniţializării unei matrice, vom iniţializa de fapt câte un vector pentru fiecare linie. Este recomandabil să facem asta respectând următorul coding style:

int produs_linie_coloana[5][5] = {
{  0  },
{  0,  1,  2,  3,  4  },
{  0,  2,  4,  6,  8  },
{  0,  3,  6,  9, 12  },
{  0,  4,  8, 12, 16  }
};

Observaţi că orice linie incompletă din matrice se va completa automat cu 0. Putem scrie un cod similar şi pentru iniţializarea matrice cu din ce în ce mai multe dimensiuni.

Probleme

Problema 1 (rezolvată)


Program care citeşte un număr N şi N note (între 1 şi 10) şi afişează procentul notelor sub 5.

Date de intrare

Pe prima linie se va afla numărul natural N ce reprezintă numărul de note. Pe a doua linie, N numere naturale ce reprezintă notele.

Date de ieşire

Se va afişa un număr real, cu trei zecimale exacte, ce reprezintă procentul notelor sub 5.

Restricţii şi Precizări

Rezolvare

Să incepem prin identificarea paşilor ce îi avem de parcurs pentru a rezolva problemei:

  1. citrea numărului N şi a vectorului de note şi stocarea lor
  2. a calcula procentul de note sub 5, va trebui să cunoaştem numărul de note sub 5
  3. afişarea rezultatului calculat

Fie V vectorul în care sunt stocate notele. Pseudocodul care calculează procentul de note sub 5 va fi:

n5 = 0
 
pentru i de la 1 la N cu pasul 1
    daca (V[i] < 5) atunci
        n5 = n5 + 1
 
procent = n5 * 100 / N
afișează procent

Programul C care implementează algoritmul descris mai sus va fi:

#include <stdio.h>
 
int main() {
    int N, v[100], i, n5;
    float procent;
 
    /* Citim numarul de note ce vor fi introduse de la tastatura */
    scanf("%d", &N);
    for (i = 0; i < N; i++) {
        /* Citim a i-a nota */
        scanf("%d", &v[i]);
    }
 
    /* In n5 vom numara cate note mai mici ca 5 au fost citite. Initial sunt 0*/
    n5 = 0;
 
    /* Parcurgem vectorul de note... */
    for (i = 0; i < N; i++) {
        /* ... si daca gasim o nota mai mica decat 5 ... */
        if (v[i] < 5) {
            /* ... vom incrementa n5. */
            n5++;
        }
    }
 
    /* Aplicam formula de calculare a procentului: cum n5, 100 si N sunt de tip
     * int, daca nu am converti una dintre ele la float, s-ar face impartire 
     * intreaga.
     */
    procent = (float)n5 * 100 / N;
 
    printf("%.3f", procent);
 
    return 0;
}

Problema 2


Să se scrie un program care citeşte un şir de numere (pozitive şi negative) şi afişează numărul de numere negative şi numărul de numere pozitive din şirul citit.

Date de intrare

Pe prima linie se va afla un număr natural N, care reprezintă dimensiunea şirului de numere. Pe a doua linie, şirul de numere pozitive şi negative.

Date de ieşire

Se vor afişa, pe aceeaşi linie, cu un spaţiu între ele, cele 2 numere naturale reprezentând numărul numerelor negative şi pozitive din şirul citit.

Restrictii si Precizari

Exemplu

Intrare Ieşire
5
-2 3 5 -7 11
2 3
5
2 3 4 4 5
0 5

Problema 3


Să se scrie un program care determină valoarea minimă dintre toate valorile maxime pe liniile unei matrice de numere intregi (punct in “şa”).

Date de intrare

Pe prima linie se vor afla două numere naturale, N şi M, ce reprezintă dimensiunile matricei (numărul de linii şi numărul de coloane). Începând cu a doua linie, vor fi câte N linii, fiecare a câte M numere întregi.

Date de ieşire

Se va afişa numărul întreg ce reprezintă punctul “şa”.

Restrictii

Exemplu

Intrare Ieşire
4 4
2 17 1 4
9 2 11 3
1 8 5 6
8 9 3 4
8

Problema 4


Se citesc 2 matrice A (m x n) şi B (p x q) de la tastatură. Afişaţi matricea C = A * B sau mesajul imposibil.

C(i, j) = ∑ A(i, k) * B(k, j), 1 ≤ i ≤ m, 1 ≤ k ≤ n = p, 1 ≤ j ≤ q

Date de intrare

Pe prima linie se vor afla două numere naturale, m şi n, ce reprezintă dimensiunile matricei A. Urmează m linii a câte n numere întregi, ce reprezintă elementele matricei A. Pe o nouă linie vor fi alte două numere naturale, p şi q, ce reprezintă dimensiunile matricei B. Urmează p linii a câte q numere întregi, ce reprezintă elementele matricei B.

Date de ieşire

Pe prima linie se vor afişa două numere naturale reprezentând dimensiunile matricei C, separate printr-un spaţiu. Urmează afişarea elementelor matricei C. În cazul în care nu se poate efectua A * B, se va afişa o singură linie cu mesajul imposibil.

Restrictii

Exemplu

Intrare Ieşire
2 1
1
2

1 3
1 2 3
2 3
1 2 3
2 4 6
2 2
1 0
0 1

1 2
5 5
imposibil

Problema 5


Program pentru interclasarea a doi vectori ordonaţi într-un singur vector ordonat.

Hint: Veţi parcurge cei 2 vectori in paralel şi veţi construi un nou vector, la care veţi adăuga, pe rând, câte un element din primul sau din al doilea vector (în funcţie de care dintre ele este mai mic).

Date de intrare

Pe prima linie se va afla un număr natural N1 ce reprezintă dimensiunea primului vector. Pe a doua linie se vor afla numere întregi ce reprezintă elementele primului vector. Pe a treia linie se va afla un număr natural N2 ce reprezintă dimensiunea celui de-al doilea vector. Pe a patra linie se vor afla numere întregi ce reprezintă elementele celui de-al doilea vector.

Date de ieşire

Se vor afişa elementele vectorului obţinut prin interclasarea celor doi vectori, separate între ele printr-un spaţiu.

Restrictii
Exemplu
Intrare Ieşire
4
-3 5 9 12
7
1 3 5 6 7 13 17
-3 1 3 5 5 6 7 9 12 13 17

Problema 6


Se citeşte o matrice pătratică A de la tastatură. Afişati toate elementele de sub diagonala secundară, pe coloane.

Date de intrare

Pe prima linie se va afla un număr natural, N, ce reprezintă numărul de linii si numărul de coloane ale matricei. Urmează N linii a câte N numere întregi, ce reprezintă elementele matricei.

Date de ieşire

Se vor afişa pe o linie, separate printr-un spaţiu, toate elementele de sub diagonala secundară.

Restrictii

Exemplu

Intrare Ieşire
4
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
14 11 15 8 12 16

Problema 7


Program pentru afişarea celei mai lungi secvenţe de elemente consecutive ordonate crescător dintr-un vector de numere naturale.

Date de intrare

Pe prima linie se va afla un număr natural, N, ce reprezintă dimensiunea vectorului. Pe a doua linie se vor afla N numere întregi ce reprezintă elementele vectorului.

Date de ieşire

Se va afişa pe o linie secvenţa de elemente consective ordonate crescător, elementele fiind despărţite între ele printr-un spaţiu.

Restrictii

Exemplu

Intrare Ieşire
9
5 3 6 2 4 6 8 4 1
2 4 6 8

Problema 8


Program pentru afişarea secvenţei de elemente consecutive de sumă maximă dintr-un vector.

Date de intrare

Pe prima linie se va afla un număr natural, N, ce reprezintă dimensiunea vectorului. Pe a doua linie se vor afla N numere întregi ce reprezintă elementele vectorului.

Date de ieşire

Se va afişa pe o linie secvenţa de elemente consecutive de sumă maximă din vectorul dat, separînd elementele între ele printr-un spaţiu.

Restrictii

Exemplu

Intrare Ieşire
12
5 0 -1 -4 2 8 3 -1 2 -5 -8 4
5 0 -1 -4 2 8 3 -1 2
Explicatii

Secventa 2 8 3 -1 2 are de asemenea suma maximă, dar vom alege ca răspuns secvenţa care începe cel mai din stânga.

Problema 9


Scrieţi un program care citeşte un şir de numere şi verifică dacă acest şir este ordonat crescator sau ordonat descrescator sau nu este ordonat sau este un şir constant. Se afişează un mesaj: “crescator” , “descrescator”, “neordonat”, “constant” .

Date de intrare

Pe prima linie se va afla un număr natural, N, ce reprezintă dimensiunea vectorului. Pe a doua linie se vor afla N numere întregi ce reprezintă elementele matricei.

Date de ieşire

Se va afişa mesajul specific.

Restrictii

Exemplu

Intrare Ieşire
5
2 3 5 7 11
crescator
4
11 2 2 5
neordonat
3
3 3 3
constant

Problema 10


Scrieţi un program care citeşte n numere reale X şi m + 1 numere întregi A şi afişează numărul de valori din X situat în fiecare din cele m intervale deschise delimitate de valorile din A.

Date de intrare

Pe prima linie se va afla numărul natural n. Pe a doua linie vor fi n numere reale. Pe a patra linie se va afla numărul natural m. Pe a cincea linie vor fi m numere întregi.

Date de ieşire

Se va afişa numărul de valori din X situat în fiecare din cele m - 1 intervale deschise delimitate de valorile din A sau mesajul Error dacă valorile din şirul A nu sunt sorte în ordine scrict crescătoare.

Restricţii

Exemplu

Intrare Ieşire
7
5.2 4.1 1.1 5 5.9 6.7 3.14

4
2 3 5 7
0 2 3
7
5.2 4.1 1.1 5 5.9 6.7 3.14

4
2 5 3 7
Error
Explicaţie

Nu sunt numere incluse în intervalul (2, 3).

În (3, 5) sunt incluse 3.14, 4.1.

În (5, 7) sunt incluse 5.2, 5.9, 6.7.

Problema 11


Program pentru calculul valorii unui polinom cu coeficienţi daţi, prin mai multe metode cu următoarea numerotare a coeficienţilor:

P(x) = c0 * xn + c1 * xn - 1 + … + cn - 1 * x + cn.

De exemplu: pentru n = 3 şi c = { 1, 2, 3, 4 }, corespunzătoare polinomului P(x) = x3 + 2 * x2 + 3 * x + 4, se poate scrie P(x) = x * (x * (x * 1 + 2) + 3) + 4

Date de intrare

Pe prima linie se vor afla două numere: un număr real x şi un număr natural n ce reprezintă gradul polinomului. Pe a doua linie, separate printr-un spaţiu, n+1 numere întregi ce reprezintă coeficienţii polinomului ( c[0], c[1], …, c[n] ).

Date de ieşire

Se va afişa valoarea polinomului cu o precizie de 2 zecimale.

Restrictii si precizari

Exemplu

Intrare Ieşire
0.5 3
1 2 3 4
6.12

Problema 12


Fie un vector de numere întregi (iniţial toate având valoarea 0) de lungime N. Se citesc de la tastatură un set de M tripleţi de forma B E V fiecare având urmatoarea semnificaţie : toate elementele din vector ale căror poziţii (indexate de la 0) sunt cuprinse între B şi E inclusiv vor fi modificate prin adunare cu V.

Afişati vectorul obţinut în urma aplicării celor M operaţii.

Date de intrare

Pe prima linie se vor afla două numere naturale: N, ce reprezintă lungimea vectorului şi M, ce reprezintă numărul de tripleţi ce vor fi citiţi de la tastatură. Pe următoarele M linii, câte trei numere naturale, B, E şi V, separate prin câte un spaţiu.

Date de ieşire

Se vor afişa pe o linie elementele vectorului obţinut în urma aplicării celor M operaţii, separate prin câte un spaţiu.

Restrictii si Precizari

Exemplu

Intrare Ieşire
5 3
1 2 3
2 4 -1
0 1 2
2 5 2 -1 -1
Explicaţie

Iniţial: 0 0 0 0 0

După (1 2 3): 0 3 3 0 0

După (2 4 -1): 0 3 2 -1 -1

După (0 1 2): 2 5 2 -1 -1