Soluzioni: Appendice 3

../_images/linea.png

A3.1 la funzone `find`

  • esercizio_01.cpp

// g++ -o Esercizio01 esercizio_01.cpp

/*
 *
 *  Si costruisca un vector di numeri interi contenente il doppio dei primi dieci numeri interi.
 *      - Si mostri che l'algoritmo std::find non trova alcuno dei primi dieci numeri dispari al suo interno.
 *      - Si trovi l'iteratore all'elemento che contiene il numero 6.
 *      - Si mostri che ognuno dei primi dieci numeri pari compare una volta sola all'interno del vector.
 */

#include <iostream>
#include <vector>
#include <algorithm> // std::find

using std::cout;
using std::endl;

int main(int argc, char** argv) {

    // Vector contenente il doppio dei primi dieci interi

    std::vector<int> doppio_interi(10, 0);
    for(int i = 1; i <= 10; i++)
        doppio_interi[i-1] = 2*i;

    /*
     *  Equivalentemente (più lento per vector di grandi dimensioni): 
     *
     *  std::vector<int> doppio_interi;
     *  for(int i = 1; i <= 10; i++)
     *      doppio_interi.push_back( 2*i );
     */

    // std::find non trova nessun numero dispari 
    for(int i = 1; i <= 19; i+=2) {
        if( std::find( doppio_interi.begin(), doppio_interi.end(), i) != doppio_interi.end() ) {
            cout << "Trovato il numero dispari " << i << endl;
        }
    }

    // Iteratore che contiene il numero 6
    std::vector<int>::const_iterator it_6 = std::find( doppio_interi.begin(), doppio_interi.end(), 6 );

    // Ognuno dei numeri pari in doppio_interi compare una volta sola
    
    std::vector<int>::iterator it, it2;
    for(it = doppio_interi.begin(); it != doppio_interi.end(); it++) {

        // Valore dell'intero nella posizione corrente
        int valore = *it;

        // Ciclo sugli elementi successivi del vector
        for( it2 = it+1; it2 != doppio_interi.end(); it2++ ) {
            // Controllo che il valore originale non si ripeta
            if( std::find( it2, doppio_interi.end(), valore ) != doppio_interi.end() ) {
                cout << "Il valore " << valore << " si ripete!" << endl;
            }
        }
    }
    
    // In alternativa, è possibile usare std::count, sempre dalla libreria algorithm
    for(unsigned int i = 0; i < doppio_interi.size(); i++) {
        int nRip = std::count( doppio_interi.begin(), doppio_interi.end(), doppio_interi[i] );
        cout << "Ripetizioni del valore " << doppio_interi[i] << " : " << nRip << endl;
    }


    return 0;
}
../_images/linea.png

A3.2 la funzone `sort`

  • esercizio02.cpp

// g++ -o Esercizio02 esercizio02.cpp ordinamento.cc

/*
 *
 *  Si costruisca un vector che contenga cento numeri interi casuali generati fra -10 e 10.
 *      - Si ordini il contenitore utilizzando l'algoritmo std::sort.
 *      - Si ordini il contenitore mettendo prima tutti i numeri positivi, ordinati fra di loro in ordine 
 *          crescente, quindi tutti quelli negativi, ordinati in ordine decrescente, utilizzando un oggetto 
 *          come algoritmo di ordinamento.
 */ 

#include <iostream>
#include <vector>
#include <algorithm> // std::sort
#include <cstdlib> // rand

#include "ordinamento.h"

using std::cout;
using std::endl;

/*
 *  Numeri casuali uniformemente distribuiti
 */
int rand_range( int min, int max ) {
    return min + rand() % (( max + 1 ) - min);
}

/*
 *  Funzione per l'ordinamento : prima tutti i positivi, ordinati in ordine crescente, poi i negativi, in ordine decrescente
 */ 
bool func_ordinamento( int a, int b ) {
    // La funzione ritorna true se a va anteposto a b 
    //
    // Consideriamo 0 come positivo

    if( a >= 0 ) {
        // a è positivo
        if( b < 0 ) {
            // se b è negativo, a va messo prima
            return true;
        } else {
            // se anche b è positivo, ordinamento crescente
            return (a < b);
            /*
             *  Equivalente a
             *
             *  if( a < b )
             *      return true;
             *  else
             *      return false;
             */
        }
    } else {
        // a è negativo
        if( b >= 0 ) {
            // se b è positivo, b va messo prima
            return false;
        } else {
            // se anche b è negativo, ordinamento decrescente
            return (a > b);
        }
    }
}

int main( int argc, char** argv ) {

    // Genero un vettore con 100 numeri casuali tra -10 e 10
    std::vector<int> numeri_casuali(100, 0);
    for(unsigned int i = 0; i < 100; i++) {
        numeri_casuali[i] = rand_range(-10, 10);
    }

    // Riordino il vector con std::sort
    std::sort( numeri_casuali.begin(), numeri_casuali.end() );

    // Riordino con una funzione
    std::sort( numeri_casuali.begin(), numeri_casuali.end(), func_ordinamento );

    // Test dell'ordinamento
    std::vector<int>::iterator it;
    cout << "Numeri ordinati usando una funzione" << endl;
    for(it = numeri_casuali.begin(); it != numeri_casuali.end(); it++) {
        cout << *it << " ";
    }
    cout << endl << endl;

    // Riordino con una classe
    ordinamento classe_ordinamento;
    std::sort( numeri_casuali.begin(), numeri_casuali.end(), classe_ordinamento );

    cout << "Numeri ordinati usando una classe" << endl;
    for(it = numeri_casuali.begin(); it != numeri_casuali.end(); it++) {
        cout << *it << " ";
    }
    cout << endl;

    return 0;
}
  • ordinamento.h

#ifndef ordinamento_h
#define ordinamento_h

class ordinamento {
    public:
        ordinamento();
        ~ordinamento();

        bool operator() (int a, int b);
};

#endif
  • ordinamento.cc

#include "ordinamento.h"

// Costruttore
ordinamento::ordinamento() {}

// Distruttore
ordinamento::~ordinamento() {}

// Operatore() per ordinare i numeri
bool ordinamento::operator() (int a, int b) {
    // La funzione ritorna true se a va anteposto a b 
    //
    // Consideriamo 0 come positivo

    if( a >= 0 ) {
        // a è positivo
        if( b < 0 ) {
            // se b è negativo, a va messo prima
            return true;
        } else {
            // se anche b è positivo, ordinamento crescente
            return (a < b);
            /*
             *  Equivalente a
             *
             *  if( a < b )
             *      return true;
             *  else
             *      return false;
             */
        }
    } else {
        // a è negativo
        if( b >= 0 ) {
            // se b è positivo, b va messo prima
            return false;
        } else {
            // se anche b è negativo, ordinamento decrescente
            return (a > b);
        }
    }
}
../_images/linea.png