prof. Nunzio Brugaletta
C++: programmazione e oggetti

EnneBi - Programmazione
Avanti - Indietro - Inizio

Utilizzo degli oggetti della classe vector

Per l'esposizione delle principali caratteristiche e delle applicazioni concrete di oggetti della classe vector, viene proposto un programma che, acquisito un vettore, per esempio di numeri interi, ordinato e un numero intero, inserisca il numero intero, all'interno del vettore, nel posto che gli compete. Il programma permette anche, alla fine, l'eliminazione di un elemento dalla struttura.

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

int main()
{
  vector<int> numeri;	/*2*/
  int i,temp;
  int cosa,pos;

  cout << "Inserisce un numero in un vettore ordinato ed" << endl;
  cout << "Elimina un elemento, conoscendone la posizione \n\n";

  // Riempimento di un vettore contenete 10 elementi

  cout << "Inserimento elementi ordinati" << endl;
  for(i=0; i<10; i++){	/*3*/
    cout << "elemento " << i << " -->";
    cin  >> temp;	/*4*/

    numeri.push_back(temp);	/*5*/
  };

  cout << "Elemento da inserire ";
  cin >> cosa;	/*6*/

  // Ricerca posizione

  pos=-1;  	/*7*/
  for(i=0; pos<0 && i<numeri.size(); i++){	/*8*/
    if(cosa<numeri.at(i))	/*9*/	
      pos = i;
  }

  // Inserimento nella posizione trovata

  if(pos>=0)  
    numeri.insert(numeri.begin()+pos,cosa);	/*10*/
  else
    numeri.push_back(cosa);	/*11*/

  // Vettore con nuovo elemento inserito

  cout << "\nNuovo vettore " << endl;
  for(i=0; i<numeri.size(); i++)	/*12*/
    cout << numeri.at(i) << "\t";
  cout << endl;

  // Eliminazione di un elemento dal vettore

  cout << "Da quale posizione togliere? ";
  cin >> pos;
  numeri.erase(numeri.begin()+pos);	/*13*/

  // Nuova visualizzazione

  cout << "\nNuovo vettore " << endl;
  for(i=0; i<numeri.size(); i++)
    cout << numeri.at(i) << "\t";
  cout << endl;

  return 0;
}

Nella 1 si dichiara l'inclusione della libreria per l'uso dei vettori.

Nella 2 si dichiara una variabile (numeri) di tipo vettore. Ogni elemento presente nel vettore sarà di tipo int. Il tipo di elemento è specificato fra parentesi angolari (< e >) subito dopo vector. Naturalmente se ci fosse stata necessità di un vettore di double con nome fatturati, la dichiarazione sarebbe stata del tipo:

vector<double> fatturati;

numeri, per quanto osservato in precedenza, è il nome di tutta la struttura.

Dalla 3 comincia un ciclo per l'input, e la successiva conservazione nel vettore, di 10 variabili di tipo int. Prima (4) viene effettuato l'input in una variabile temporanea e, subito dopo (5), viene ordinato al vettore di inserire il valore ricevuto, all'interno della struttura, in coda. Tutto ciò viene fatto passando il parametro temp (fra parentesi) alla funzione membro push_back, applicata (l'operatore .) al vettore numeri.

Nella 6 viene acquisito il nuovo elemento da inserire nel vettore. Il primo problema da risolvere, a questo punto, è quello di trovare la posizione corretta in cui inserire il numero e, di ciò, si occupa il ciclo successivo. In dettaglio il ciclo si occuperà di trovare la posizione del primo numero, presente nel vettore, maggiore, in valore, del valore contenuto in cosa. Quella è la posizione che deve occupare il numero acquisito come input. Trovata la posizione si tratterà semplicemente di inserire l'elemento. Esiste un metodo, non trattato in questa sede, che potrebbe restituire la posizione di un elemento cercato ma qui si è preferito utilizzare un ciclo per la scansione lineare della struttura.

Nella 7 la posizione viene inizializzata a -1 che, quindi, sarà l'indicatore di posizione non trovata. Il controllo presente in 8 permette di uscire fuori dal ciclo nel caso in cui si trova un elemento del vettore maggiore del numero dato (controllo pos<0 non più valido perché contiene una posizione rappresentata dallo zero o da un numero positivo) o nel caso in cui termina il vettore (i<numeri.size()). Può infatti accadere che nessun elemento del vettore sia maggiore del dato di input e, in questo caso specifico, il numero dovrà essere inserito come ultimo elemento. Si permane dentro il ciclo se sono verificate contemporaneamente (operatore &&) la condizione pos ancora con valore negativo e non si è ancora concluso l'esame degli elementi del vettore.

Il metodo size() applicato al vettore numeri fornisce la quantità degli elementi presenti nel vettore. Nel caso specifico si conosce il numero degli elementi e, infatti, si sarebbe potuto specificare 10, ma, in generale, si ricorre a detta funzione per conoscere la quantità degli elementi presenti in un vettore.

La 9 coinvolge un confronto con un elemento del vettore (quello di posizione generica i). Il metodo at applicato al vettore numeri permette l'accesso all'elemento del vettore individuato dall'indice specificato.

In 10, se si è trovato un elemento del vettore maggiore del numero da inserire (informazione fornita dalla posizione non negativa), si inserisce il numero fornendolo, assieme alla posizione di inserimento, alla funzione insert applicata al vettore. La posizione è ottenuta sommando il valore relativo che si è trovato (pos) a numeri.begin(), che indica la posizione iniziale di memorizzazione della struttura. Se non si è trovata una posizione, il numero è maggiore di tutti gli elementi del vettore e si invia al vettore senza specificare una posizione (11) in modo da inserirlo in coda a quelli esistenti.

Il ciclo che comincia da 12 si occupa di effettuare l'output del vettore in modo da controllare l'avvenuto inserimento.

Per ordinare ad un vettore di eliminare un elemento, si richiama la funzione erase del vettore, specificando, come in 13, la posizione dell'elemento da eliminare. Anche qui la posizione come in 10 è espressa come somma della posizione relativa (scostamento) rispetto all'inizio del vettore.

Il ciclo per l'inserimento dei numeri della sequenza ordinata, per come è stato implementato, non fa alcun controllo sul fatto che la sequenza sia effettivamente crescente. Può essere interessante modificare il ciclo in modo che faccia in modo che ogni input abbia un valore maggiore del precedente, prima di inviarli al vettore per la conservazione, allo scopo di avere una sequenza crescente.

...
for(i=0; i<10; i++){
  cout << "elemento " << i << " -->";
  cin  >> temp;

  // verifica ordinamento

  if(!i || temp>numeri.at(i-1))	/*1*/
    numeri.push_back(temp);	/*2*/
  else{
    cout << "La sequenza deve essere ordinata" << endl
         << "Ripetere l\'inserimento" << endl;
    i--;	/*3*/
  };
};
...

È il controllo in 1 che, sostanzialmente, permette di stabilire se la sequenza è crescente. Se si tratta del primo elemento (!i cioè se i è 0) o l'input è maggiore dell'elemento inserito precedentemente (quello con indice i-1), si inserisce in coda (2). L'ultima condizione non avrebbe senso per il primo elemento ma, per l'operatore OR (||), basta che la prima condizione sia verificata per non procedere oltre.

Se il valore inserito non è maggiore del precedente, basta decrementare l'indice del ciclo (3). Questa operazione è necessaria poiché, in ogni caso, per effetto del costrutto for, l'indice verrebbe incrementato prima di passare al controllo del ciclo.



Avanti - Indietro - Inizio

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