Clasa a V-a lecția 6 S13

From Algopedia
Jump to navigationJump to search

Instrucțiunea for

Precum am văzut în exemplele anterioare de multe ori avem nevoie să executăm o buclă WHILE-DO de n ori, folosind un contor. Aceasta este un tip particular de buclă WHILE-DO, și anume o buclă cu număr cunoscut de pași. Pentru acest tip de bucle limbajul C ne permite o prescurtare, folosind instrucțiunea for.

Schemă logică Implementare cu while Implementare cu for
 i = 0;
 while ( i < n ) {
   ... execută corpul
       buclei...
   i = i + 1;
 }
 for ( i = 0; i < n; i++ ) {
   ... execută corpul
       buclei...
 }

Mecanism:

  • Pasul 1: Se executa initializarea
  • Pasul 2: Se testeaza conditia. Daca conditia este adevarata atunci trecem la pasul 3. Daca conditia este falsa se trece la pasul 5
  • Pasul 3: Se executa pachetul de instructiuni “Prel”
  • Pasul 4: Se executa incrementarea si se revine la pasul 2
  • Pasul 5: Stop

Aplicatii

Suma primelor n numere naturale

#include <stdio.h>

int main(){
    ///declaram 2 variabile de tip FILE*
    FILE *fin, *fout;
    ///vom asocia var. de tip file, 2 fisiere externe
    fin = fopen("date.in", "r");
    fout = fopen("date.out", "w");
    int n, i;
    long long s;
    ///citim din fisier datele de intrare
    fscanf(fin, "%d", &n);
    ///calculam suma primelor n numere
    s = 0;
    for(i = 1; i <= n; i++ )
      s = s + i;
    ///afisam rezultatul in fisierul de iesire
    fprintf(fout, "%lld", s);
    fclose(fin);
    fclose(fout);
    return 0;
}

Secvențe

Vom numi secventa un sir de n numere.

Citirea unei secvențe

Deoarece nu avem unde păstra numerele unei secvențe, le vom citi, pe rînd, în aceeași variabilă. Pentru a ști cîte numere citim (cîte numere are secvența) de obicei vom citi mai întîi numărul de numere din secvență, n și apoi cele n numerele din secvență, într-o buclă WHILE-DO. Exemplu:

Citire secvență
 fscanf( fin, "%d", &n );
 i = 0;
 while ( i < n ) {
   fscanf( fin, "%d", &a );
   i = i + 1;
 }
 fscanf( fin, "%d", &n );
 
 for (i = 0; i < n; i = i + 1) {
   fscanf( fin, "%d", &a );
   
 }

Suma a n numere citite

#include <stdio.h>

int main(){
    ///declaram 2 variabile de tip FILE*
    FILE *fin, *fout;
    ///vom asocia var. de tip file, 2 fisiere externe
    fin = fopen("date.in", "r");
    fout = fopen("date.out", "w");
    int n, i, nr;
    long long s;
    ///citim din fisier datele de intrare
    fscanf(fin, "%d", &n);
    ///calculam suma primelor n numere
    s = 0;
    for(i = 1; i <= n; i++ ){
      fscanf(fin, "%d", &nr);
      s = s + nr;
    }
    ///afisam rezultatul in fisierul de iesire
    fprintf(fout, "%lld", s);
    fclose(fin);
    fclose(fout);
    return 0;
}

Elementul maxim într-o secvență

Dată o secvență de n numere să se afișeze elementul cel mai mare (maxim) din secvență.

//fara fisiere
#include <stdio.h>

int main(){
  int  n, i, nr, max;
  scanf( "%d", &n);           // citim numarul de valori din sir
  scanf( "%d", &nr );         // citim primul numar din sir
  max = nr;                    // initializam maximul cu prima valoare di sir
  for(i = 1; i < n; i++ ){          // mai avem de citit n-1 valori
    scanf( "%d", &nr );             // fiecare valoare citita
    if( nr > max )                  // daca noua valoare citita este mai mare decat maxim
      max = nr;                     // maximul va deveni acea valoare
  }
  printf( "%d", max );
  return 0;
}


Numărul maxim în secvență
 #include <stdio.h>

 int main() {
   FILE *fin, *fout;
   int n, i, a, max;

   fin = fopen( "maxim.in", "r" );
   fscanf( fin, "%d", &n );
   //citim prima val din sir si o punem direct in variabila maxim
   fscanf( fin, "%d", &max );
   for ( i = 1; i < n; i++ ) {
     fscanf( fin, "%d", &a );
     if ( max < a )
       max = a;
   }
   fclose( fin );

   fout = fopen( "maxim.out", "w" );
   fprintf( fout, "%d", max );
   fclose( fout );
   return 0;
 }

Observații:

  • Elementul maxim se inițializează cu primul element al șirului nu cu valoarea zero. Întotdeauna vom inițializa maximul cu un element al secvenței. De ce?
    • Este bine să fim ordonați și consecvenți: max este doar un candidat la maxim, dintre elementele secvenței, pînă la final, cînd devine chiar maximul. Ce fel de candidat este el dacă este un străin, nici măcar nu face parte din secvență?
    • În viitor putem avea și elemente negative.
    • Dacă avem o greșeală în program detecția ei și corectura sînt mai grele atunci cînd max poate lua valori în afara elementelor din secvență.
  • Pentru a calcula elementul minim într-o secvență singurul lucru care se modifică în schema de mai sus este semnul comparației max < a, din mai mic < în mai mare >.

Laborator

Secvență în ordine crescătoare

Dată o secvență cu n numere să se spună dacă cele n numere din secvență sînt in ordine crescătoare (fiecare număr este mai mic sau egal cu cel de după el).

Secvență crescătoare
 #include <stdio.h>

 int main() {
   FILE *fin, *fout;
   int n, i, a, b, cresc;

   fin = fopen( "crescatoare.in", "r" );
   fscanf( fin, "%d", &n );
   fscanf( fin, "%d", &a );
   cresc = 1;
   i = 1;
   while ( i < n && cresc == 1) {
     fscanf( fin, "%d", &b );
     if ( b < a )
       cresc = 0;
     a = b;
     i++;
   }
   fclose( fin );

   fout = fopen( "crescatoare.out", "w" );
   if ( cresc == 1 )
     fprintf( fout, "da\n" );
   else
     fprintf( fout, "nu\n" );
   fclose( fout );
   return 0;
 }

Observații:

  • Nu folosim instrucțiunea for deoarece nu se știe de cîte ori se va executa bucla while (nu avem un ciclu cu număr cunoscut de pași).
  • Trebuie să ținem minte elementul anterior în secvență, pentru a-l putea compara cu elementul curent. Vom vedea că în alte probleme vom avea nevoie să ținem minte două sau chiar și trei elemente anterioare.
  • Încercaţi să scrieţi algoritmul fără a folosi steguleţe.

Sirul lui Fibbonacci

Tema teorie

Pbinfo: Tema S7_Teorie