prof. Nunzio Brugaletta
C++: programmazione e oggetti

EnneBi - Programmazione
Avanti - Indietro - Inizio

Il metodo top-down: un esempio step by step

Applicare il metodo top-down alla risoluzione di un problema vuol dire risolvere il problema, in una primo approccio, come se il linguaggio utilizzato mettesse a disposizione istruzioni di alto livello che riescono a svolgere una parte del problema e, successivamente, passare ad occuparsi della risoluzione delle singole parti.

Come applicazione viene proposto un esempio di selezione: dato un vettore di interi non nulli, si vuole generare il sottoinsieme dei pari.

Il primo passo da compiere è stabilire quali sono le fasi che portano alla soluzione del problema:

#include <iostream>	/*1*/
#include <vector>	/*1*/
using namespace std;

// prototitpi

int main()
{
  vector<int> numeri, pari;	/*2*/

  cout << "Estrazione di sottoinsieme:" << endl
       << "data una sequenza di interi positivi" << endl
       << "comunica il sottoinsieme dei pari" << endl;

  // input numeri da elaborare
  
  // estrazione sottoinsieme dei pari
  
  // output sottoinsieme pari

  return 0;  
}

In questa prima stesura, a parte le inclusioni che servono (1) e la dichiarazione delle variabili necessarie alla risoluzione del problema (2), sono presenti soltanto righe di commento utilizzate per stabilire quali cose fare e in quale ordine.

Stabilita, per grandi linee, la sequenza delle funzioni da svolgere, si passa a chiarire meglio la prima funzione: quella che si deve occupare dell'input dei numeri da elaborare. In questa sede è importante solo stabilire cosa la funzione deve fare e come si deve utilizzare.

In conseguenza, a quanto osservato, si potrà aggiungere al programma il prototipo e la chiamata alla funzione:

#include <iostream>
#include <vector>
using namespace std;

// prototitpi

vector<int> inputNumeri();	/*1*/

int main()
{
  vector<int> numeri, pari;

  cout << "Estrazione di sottoinsieme:" << endl
       << "data una sequenza di interi positivi" << endl
       << "comunica il sottoinsieme dei pari" << endl;

  // input numeri da elaborare

  numeri = inputNumeri();	/*2*/

  // estrazione sottoinsieme dei pari

  // output sottoinsieme pari

  return 0;
}

Nel prototipo (1) è evidenziato il fatto che la funziona ritorna un oggetto di tipo vector<int>. Nella chiamata alla funzione (2), main assegna il valore di ritorno della funzione a numeri in cui si ritroveranno i valori acquisiti dalla funzione.

Con lo stesso procedimento si stabiliscono i compiti e le modalità d'uso delle rimanenti due funzioni:

Il programma, con i prototipi e le chiamate alle funzioni, sarà:

#include <iostream>
#include <vector>
using namespace std;

// prototitpi

vector<int> inputNumeri();
vector<int> estraiPari(vector<int>);
void outputPari(vector<int>);

int main()
{
  vector<int> numeri, pari;

  cout << "Estrazione di sottoinsieme:" << endl
       << "data una sequenza di interi positivi" << endl
       << "comunica il sottoinsieme dei pari" << endl;

  // input numeri da elaborare

  numeri = inputNumeri();

  // estrazione sottoinsieme dei pari

  pari = estraiPari(numeri);

  // output sottoinsieme pari

  outputPari(pari);

  return 0;
}

Il programma è formalmente completo: sono specificate le funzioni che assolve e la sequenza delle fasi di elaborazione. Naturalmente per poterlo compilare e, successivamente, eseguire è necessario aggiungere il codice delle funzioni. Finora si è specificato cosa le funzioni fanno, ora dovrà essere specificato come lo fanno, ovvero si dovrà aggiungere la definizione delle funzioni.

...
// prototitpi

vector<int> inputNumeri();
vector<int> estraiPari(vector<int>);
void outputPari(vector<int>);

int main()
{
  ...
}

// input numeri da elaborare

vector<int> inputNumeri()
{
  vector<int> num;
  int temp;

  cout << "Numero da elaborare (0 per finire) ";
  cin >> temp;
  while(temp){
    num.push_back(temp);

    cout << "Numero da elaborare (0 per finire) ";
    cin >> temp; 
  }
  return num;
}

// estrazione sottoinsieme pari

vector<int> estraiPari(vector<int> num)
{
  vector<int> numpari; 
  int i;

  for(i=0;i<num.size();i++){
    if(!(num.at(i)%2))	/*1*/
      numpari.push_back(num.at(i));	/*2*/
  }
  return numpari;
}

// output sottoinsieme pari

void outputPari(vector<int> numpari)
{
  int i;

  cout << "Sottoinsieme pari" << endl;

  for(i=0;i<numpari.size();i++)
    cout << " " << numpari.at(i);
  cout << endl;
}

La funzione che genera il sottoinsieme dei pari, esamina il vettore da elaborare e se trova un elemento pari (controllo in 1), lo carica nel vettore dei pari (2).

Le altre funzioni, per la semplicità del codice, non necessitano di ulteriori commenti.



Avanti - Indietro - Inizio

http://ennebi.solira.org
ennebi@solira.org