Funzioni di tipo vector, dubbi

di il
15 risposte

Funzioni di tipo vector, dubbi

Buona sera sto creando questa funzione che aggiunge un elemento in un vettore e sposta tutti gli elementi (dall'elemento inserito in poi) di una posizione piú avanti:

#include <iostream>
#include <vector>
using namespace std;
vector<int> insert(vector<int>, int, int);//aggiunge a v in posizione i il valore di val

int main()
{
 vector<int> v = {1, 2, 3, 4, 5};
 int i = 1;
 int val = 0;
 insert (v, i, val);
 for (int j = 0; j < v.size(); j++) cout << v[i] << " ";
 cout << endl;
}
vector<int> insert(vector<int> v, int i, int val)
{ 
 v.push_back(v[v.size()-1]);
 for (int j = v.size()-1; j >= i; j--) 
 {
  v[j] = v[j-1];
  if (j == i) v[j] = val;
 } 
 return v;
}
So che una funzione di tipo int ad esempio la funzione somma deve restituire un int che in questo caso é la somma di a e b:

int somma(int a, int b)
{
 return a + b;
}
Ma una funzione di tipo vector<int> deve per forza restituire un vector<int> oppure no ? Come funziona?

15 Risposte

  • Re: Funzioni di tipo vector, dubbi

    Il linguaggio in se non ti obbliga a restituire nulla, ma nel caso specifico perdi le modifiche al vector se non lo fai.
    Meglio passare il vector per reference e restituirlo per reference piuttosto che per value.
    
    vector<int>& insert(vector<int>& v, int i, int val)
    
  • Re: Funzioni di tipo vector, dubbi

    SuperManPC ha scritto:


    Ma una funzione di tipo vector<int> deve per forza restituire un vector<int> oppure no ? Come funziona?
    Ciao, una volta che hai fissato il tipo di ritorno della funzione, mi sembra ovvio che essa debba ritornare quella roba lì...
    Nel caso specifico comunque opterei per una funzione di tipo void a cui passare il vector per riferimento, poi ovviamente tutto dipende dall'utilizzo che vuoi farne di quella funzione.
  • Re: Funzioni di tipo vector, dubbi

    Grazie per le risposte
  • Re: Funzioni di tipo vector, dubbi

    Ci sono riuscito, ho visto che funziona ugualmente sia definendo la funzione come void che come vector<int> e usando return vector alla fine. Ma quindi grazie al passaggio per riferimento è possibile ritornare un vettore da una funzione, in particolare la funziona ritorna il vettore oppure lo spazio di memoria che lo contiene?
    Comunque ho fatto così:
    
    #include <iostream>
    #include <vector>
    using namespace std;
    vector<int> insert(vector<int>&, int, int);//aggiunge a v in posizione i il valore di val
    
    int main()
    {
     vector<int> v = {1, 2, 3, 4, 5};
     int i = 1;
     int val = 0;
     insert (v, i, val);
     for (int j = 0; j < v.size(); j++) cout << v[j] << " ";
     cout << endl;
    }
    vector<int> insert(vector<int>& v, int i, int val)
    { 
     v.push_back(v[v.size()-1]);
     for (int j = v.size()-1; j >= i; j--) 
     {
      v[j] = v[j-1];
      if (j == i) v[j] = val;
     } 
     return v;
    }
     
    
  • Re: Funzioni di tipo vector, dubbi

    grazie al passaggio per riferimento è possibile ritornare un vettore
    No, stai facendo confusione, i due concetti non sono legati.

    A che ti serve in questo caso restituire il vector se non lo utilizzi nella chiamata? In questo caso è bene che la funzione sia void ma il vector in ingresso, per essere modificato, deve essere passato per reference. Quindi

    void insert(vector<int>& v, int i, int val)

    senza return
  • Re: Funzioni di tipo vector, dubbi

    Ah ok, ho dovuto farla cosí perché lo richiedeva l' esercizio, ma invece per la funzione:
    nel caso di return v la funzione prende il valore del vettore, potresti spiegarmi questo?
  • Re: Funzioni di tipo vector, dubbi

    Strano che l'esercizio te lo chieda, forse lo scopo è assegnare il risultato ad altro vettore nel main.

    Mostra l'esercizio
  • Re: Funzioni di tipo vector, dubbi

    Questa é la versione completa del testo, io sono alla prima parte.

    Scrivere una funzione std::vector<int> insert(std::vector v, int i, int val) che aggiunge a v in posizione i il valore di
    val. La lunghezza di v deve essere incrementata di 1 e tutto l’eventuale contenuto di v, dalla posizione i (compresa) fino alla
    fine, deve essere spostato in avanti di una posizione. NOTA: siccome è previsto che il vettore si incrementi di dimensione,
    le posizioni di inserimento valide sono tutte quelle esistenti (da 0 a v.size()-1) e anche una oltre l’ultima (la posizione
    v.size()), quindi i2 [0,v.size()]. Se i non è compreso in questo intervallo sollevare una eccezione int.
    [SUGGERIMENTO: Inserire in coda a v il suo ultimo elemento (se esiste), spostare in avanti di una posizione gli elementi di
    v a partire dalla posizione i in avanti (copiandoli a partire dal fondo in modo da non sovrascriverli) e assegnare il valore da
    inserire nella posizione i.]
    Scrivere un programma di test che dichiara un std::vector<int> e fa il test della funzione insert nei seguenti casi:
    (a) Inserimento in v vuoto
    (b) Inserimento in testa (in posizione 0) a v non vuoto
    (c) Inserimento in coda (dopo l’ultima posizione) a v non vuoto
    (d) Inserimento in posizione generica (non testa, non coda) in v non vuoto
    (e) Inserimento in posizione non valida (usare try . . . catch per trattare l’eccezione).
  • Re: Funzioni di tipo vector, dubbi

    Beh allora dovresti dirle prima queste cose. L'esercizio vuole espressamente che l'argomento NON sia passato per riferimento e che l'elaborazione termini con la restituzione della copia del vectore al chiamante. Quindi devi usare

    std::vector<int> insert(std::vector v, int i, int val)

    e soprattutto cambiare la chiamata che fai nel main della insert. Pensaci.
  • Re: Funzioni di tipo vector, dubbi

    Senza il passaggio per riferimento non ci riesco, ma in che senso l'elaborazione termini con la restituzione della copia del vectore al chiamante, devo fare una copia del vectore v in un altro vectore r e poi restituire r?
  • Re: Funzioni di tipo vector, dubbi

    Per ora sono riuscito a fare questo ma senza riferimento non so proprio come fare:
    
    #include <iostream>
    #include <vector>
    #include <string>
    
    std::vector<int> insert(std::vector<int>, int, int);//aggiunge a v in posizione i il valore di val
    
    int main()
    {
     /*std::vector<int> vuoto; con vettore vuoto da errore
     int i = 0;
     int val = 0;
     insert (vuoto, i, val);
     for (int j = 0; j <= vuoto.size(); j++) std::cout << vuoto[j] << " ";
     std::cout << std::endl;*/
     std::vector<int> v = {0, 1};
     insert (v, 0, 2);
     std::cout << "Inserimento in testa: ";
     for (int j = 0; j < v.size(); j++) std::cout << v[j] << " ";
     std::cout << std::endl;
    
     std::vector<int> v1 = {0, 1};
     insert (v1, 2, 2);
     std::cout << "Inserimento in coda: ";
     for (int j = 0; j < v1.size(); j++) std::cout << v1[j] << " ";
     std::cout << std::endl;
    
     std::vector<int> v2 = {0, 1};
     insert (v2, 1, 2);
     std::cout << "Inserimento in posizione generica: ";
     for (int j = 0; j < v2.size(); j++) std::cout << v2[j] << " ";
     std::cout << std::endl;
    
     std::vector<int> v3 = {0, 1};
     try{
      insert (v3, 3, 2);
      std::cout << "Inserimento in posizione non valida: ";
      for (int j = 0; j < v3.size(); j++) std::cout << v3[j] << " ";
     }
     catch(std::string &err){
      std::cout << err;
     }
     std::cout << std::endl;
    }
    std::vector<int> insert(std::vector<int> v, int i, int val)
    { 
     std::string err = "Inserimento in posizione non valida";
     if (i < 0 || i > v.size()) throw err;
     v.push_back(v[v.size()-1]);
     for (int j = v.size()-1; j >= i; j--) 
     {
      v[j] = v[j-1];
      if (j == i) v[j] = val;
     } 
     return v;
    }
     
    
  • Re: Funzioni di tipo vector, dubbi

    oregon ha scritto:


    Strano che l'esercizio te lo chieda, forse lo scopo è assegnare il risultato ad altro vettore nel main.

    Mostra l'esercizio
    Grazie per il suggerimento perché ci sarebbe voluto troppo tempo per arrivarci:
    alla fine nel main dichiaro un vector r a cui assegno la funzione insert che restituisce un vettore.
    Quindi bisognava passare il valore restituito della funzione ad un vectore nel main altrimenti mi sembra che venga perso tutto il lavoro della funzione...
    Mi rimane solo il caso in cui il vettore é vuoto, non so se é giusto che dia errore oppure no.
    
    #include <iostream>
    #include <vector>
    #include <string>
    
    std::vector<int> insert(std::vector<int>, int, int);//aggiunge a v in posizione i il valore di val
    
    int main()
    {
     
     /*std::vector<int> vuoto; 
     std::vector<int> r0;
     r0 = insert (vuoto, 1, 0);
     std::cout << "Inserimento in v vuoto: ";
     for (int j = 0; j <= r0.size(); j++) std::cout << r0[j] << " ";
     std::cout << std::endl;*/
    
     std::vector<int> v = {0, 1};
     std::vector<int> r;
     r = insert (v, 0, 2);
     std::cout << "Inserimento in testa: ";
     for (int j = 0; j < r.size(); j++) std::cout << r[j] << " ";
     std::cout << std::endl;
    
     std::vector<int> v1 = {0, 1};
     std::vector<int> r1;
     r1 = insert (v1, 2, 2);
     std::cout << "Inserimento in coda: ";
     for (int j = 0; j < r1.size(); j++) std::cout << r1[j] << " ";
     std::cout << std::endl;
    
     std::vector<int> v2 = {0, 1};
     std::vector<int> r2;
     r2 = insert (v2, 1, 2);
     std::cout << "Inserimento in posizione generica: ";
     for (int j = 0; j < r2.size(); j++) std::cout << r2[j] << " ";
     std::cout << std::endl;
    
     std::vector<int> v3 = {0, 1};
     std::vector<int> r3;
     try{
      r3 = insert (v3, 3, 2);
      std::cout << "Inserimento in posizione non valida: ";
      for (int j = 0; j < r3.size(); j++) std::cout << r3[j] << " ";
     }
     catch(std::string &err){
      std::cout << err;
     }
     std::cout << std::endl;
    }
    std::vector<int> insert(std::vector<int> v, int i, int val)
    { 
     std::string err = "Inserimento in posizione non valida";
     if (i < 0 || i > v.size()) throw err;
     v.push_back(v[v.size()-1]);
     for (int j = v.size()-1; j >= i; j--) 
     {
      v[j] = v[j-1];
      if (j == i) v[j] = val;
     } 
     return v;
    }
     
    
  • Re: Funzioni di tipo vector, dubbi

    Va bene, anche se è preferibile usare le eccezioni della libreria standard o una da esse derivata.
    Il vettore nel mai si può inizializzare così:
    
    std::vector<int> r2 = insert (v2, 1, 2);
    
  • Re: Funzioni di tipo vector, dubbi

    Alexv ha scritto:


    Va bene, anche se è preferibile usare le eccezioni della libreria standard o una da esse derivata.
    Il vettore nel mai si può inizializzare così:
    
    std::vector<int> r2 = insert (v2, 1, 2);
    
    Ah ok grazie. Quali sarebbero le eccezioni della libreira standard?
Devi accedere o registrarti per scrivere nel forum
15 risposte