Clasa a V-a lecția 22 - 19 ian 2020

From Algopedia
Jump to navigationJump to search

Tema - rezolvări

Problema numchar

Iată o rezolvare posibilă la problema numchar:

#include <stdio.h>

int main() {
  FILE *fin, *fout;
  int n, i, nl, nc;
  char c;

  fin = fopen( "numchar.in", "r" );
  fscanf( fin, "%d", &n );
  fgetc( fin );

  nl = nc = 0;
  for ( i = 0; i < n; i++ ) {
    c = fgetc( fin );
    if ( (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') )
      nl++;
    else if ( c >= '0' && c <= '9' )
      nc++;
  }
  fclose( fin );

  fout = fopen( "numchar.out", "w" );
  fprintf( fout, "%d %d", nl, nc );
  fclose( fout );

  return 0;
}

De remarcat faptul că testarea dacă c este cifră se face pe ramura else a primului test, dacă este literă.

Lecție

A fost o lecție de lucru, în care am rezolvat la calculator o serie de probleme. Cei care nu au reușit să le termineîn timpul lecției, le vor considera temă și le vor rezolva acasă.

Problema alfanumeric

Iată o rezolvare posibilă la problema alfanumeric:

#include <stdio.h>

int main() {
  FILE *fin, *fout;
  int n, i, s;
  char c;

  fin = fopen( "alfanumeric.in", "r" );
  fscanf( fin, "%d", &n );
  fgetc( fin );

  fout = fopen( "alfanumeric.out", "w" );
  s = 0;
  for ( i = 0; i < n; i++ ) {
    c = fgetc( fin );
    if ( c >= 'a' && c <= 'z' ) {
      c = 'A' + c - 'a';
      fputc( c, fout );
    } else if ( c >= 'A' && c <= 'Z' )
      fputc( c, fout );
    else if ( c >= '0' && c <= '9' )
      s = s + c - '0';
    fgetc( fin ); // elimina spatiul dintre caractere
  }
  fclose( fin );

  fprintf( fout, "\n%d", s );
  fclose( fout );

  return 0;
}

De remarcat că cele trei cazuri, literă mică, literă mare sau cifra se vor înlănțui pe ramurile else ale if-urilor respective. Nu uitați să citiți și caracterul spațiu dintre caractere.

Problema plusminus

Problema plusminus are o rezolvare elegantă dacă, în loc să citim cîte o linie, așa cum am fi tentați (adică un număr, un spațiu, un semn și finalul de linie \n), vom despărți intrarea astfel:

  • Primul număr din secvență
  • spațiu, semn, \n, încă un număr
  • spațiu, semn, \n, încă un număr

...

  • spațiu, semn, \n, încă un număr
  • \n final (ultima linie are doar un număr și un \n)

Astfel, vom citi primul număr și încă un caracter. Cîtă vreme acel caracter este spațiu, continuăm bucla. Ne oprim cînd dăm de \n. Astfel evităm să citim incorect caractere după \n, cum se întîmplă în soluțiile unora din voi.

Iată o soluție bazată pe aceste idei:

#include <stdio.h>

int main() {
  FILE *fin, *fout;
  int n, s;
  char c;

  s = 0;
  fin = fopen( "plusminus.in", "r" );
  fscanf( fin, "%d", &s );
  c = fgetc( fin );
  while ( c == ' ' ) {
    c = fgetc( fin );
    fscanf( fin, "%d", &n );
    if ( c == '+' )
      s = s + n;
    else
      s = s - n;
    c = fgetc( fin );
  }
  fclose( fin );

  fout = fopen( "plusminus.out", "w" );
  fprintf( fout, "%d", s );
  fclose( fout );

  return 0;
}

Problema cezar

Problema cezar este o problemă didactică. Se poate rezolva cu o serie de condiții, corect ordonate. Cu toate acestea, o soluție elegantă ar fi să evităm folosirea condițiilor și să ne folosim doar de calcule. Reamintesc că operația modulo este una foarte importantă și ajută în multe situații când trebuie să parcurgem circular un șir. În cazul de față, trebuie să știm să ne întoarcem la prima literă a alfabetului când am ajuns la ultima, z. În felul de acesta, folosim doar calcule.

Iată o posibilă soluție:

#include <stdio.h>

int main() {
  FILE *fin, *fout;
  char c;

  fin = fopen( "cezar.in", "r" );
  fout = fopen( "cezar.out", "w" );
  c = fgetc( fin );
  while ( c != '\n' ) {
    c = 'a' + (c - 'a' + 1) % 26;
    fputc( c, fout );
    c = fgetc( fin );
  }
  fclose( fin );

  fputc( '\n', fout );
  fclose( fout );

  return 0;
}

Temă

Tema 22 să se rezolve următoarele probleme (program C trimis la vianuarena). Tema constă din exercițiile din clasă plus încă trei exerciții:

Rezolvări aici [1]