Unione dei vettori + ordinamento

di il
9 risposte

Unione dei vettori + ordinamento

Salve a tutti, avrei bisogno di un aiuto nella realizzazione di questo programma:
Leggere alcuni numeri interi dalla tastiera, inserire i pari nel vettore A e i dispari nel vettore b. Terminare l'inserimento quando uno dei due vettori è pieno. I due vettori hanno 5 posti. Unire i due vettori inserendo i numeri in ordine crescente. Stampare il terzo vettore.

Io ho creato questa stringa di codice ma mi da errore nella parte evidenziata in grassetto:
//
#include <iostream>
using namespace std;
int main()
{int ca, cb, c, n, i, x, a[5], b[5], m, temp, j, mini;
 c=1;
 ca=0;
 cb=0;
 cout<<"Inserisci numero: ";
 cin>>n;
 if(n%2==0)
   {a[ca]=n;
    ca++;
   }
 else
   {b[cb]=n;
    cb++;
   }
 do
 {cout<<"Inserisci numero: ";
  cin>>n;
  c++;
  if(n%2==0)
   {a[ca]=n;
    ca++;
   }
 else
   {b[cb]=n;
    cb++;
   } 
 }while(ca!=5 && cb!=5);
  int v[c];
 ca=0;
 cb=0;
[b] for(i=0;i<=c/2;i++)
    {if(b>a)
       {v[i]=b[cb];
        cb++;
        v[i]=a[ca];
        ca++;
       }
    else
       {v[i]=a[ca];
        ca++;
        v[i]=b[cb];
        cb++;
       }[/b]
    }
 for(j=0;j<c-1;j++)
    {mini=j;
     for(x=j+1;x<c;x++)
        {if(v[x]<v[mini])
           {mini=x;
            temp=v[mini];
            v[mini]=v[i];
            v[i]=temp;
           }
        }
     }
 for(m=0;m<c;m++)
    {cout<<v[m]<<" ";
    }
 cin>>n;
 return 0;
}

il programma quando lo avvio mi copia i primi 4 numeri del vettore b (nel caso appunto il vettore b sia pieno) per poi lasciarmi 3 zeri dopo senza nemmeno facendo caso al vettore A (tra l'altro non me li mette nemmeno in ordine).

C'è un modo per migliorare questo codice e farlo funzionare? Vi metto anche un immagine di quello che mi si presenta:

9 Risposte

  • Re: Unione dei vettori + ordinamento

    Questa if

    if(b>a)

    non ha senso
  • Re: Unione dei vettori + ordinamento

    oregon ha scritto:


    Questa if

    if(b>a)

    non ha senso
    Puoi darmi maggiori informazioni? Ho usato quell'if per dire che se il vettore b è più grande di a allora inizia da b, in modo che non ci siano spazi liberi dopo. Essendo sbagliato. C'è un altro modo per risolvere questo problema? Abbiamo da poco iniziato ad usare i vettori quindi non conosco ancora tutto.
  • Re: Unione dei vettori + ordinamento

    Provo a spiegarti io una cosa: quando si parla di variabili di tipo array, il C/C++ gestisce dietro le quinte il tutto con dei puntatori. Utilizzare l'identificatore di un array equivale a utilizzare il puntatore al suo primo elemento (infatti de-referenziandolo (--> *a) dovresti ottenere il valore del suo primo elemento).
    Tu sai che un puntatore rappresenta un indirizzo di memoria. Ora, fare un if in cui si confrontano due puntatori vale a dire mettere a confronto due indirizzo di memoria. Quindi if(b>a) non sta per "se l'array b è più grande dell'array a" bensì "l'indirizzo di memoria 0x6dfef0 è più grande dell'indirizzo 0x6dfefc" (gli indirizzi li ho sparati a caso...)

    Per fare ciò che dici tu dovresti fare una cosa del genere:
    int lunghezzaA=sizeof(a)/sizeof(int); ---> così ottieni la lunghezza dell'array a
    int lunghezzaB=sizeof(b)/sizeof(int); ---> così ottieni la lunghezza dell'array b
    if(lunghezzaB>lunghezzaA)
    ...
  • Re: Unione dei vettori + ordinamento

    2_3rr0r5 ha scritto:


    Provo a spiegarti io una cosa: quando si parla di variabili di tipo array, il C/C++ gestisce dietro le quinte il tutto con dei puntatori. Utilizzare l'identificatore di un array equivale a utilizzare il puntatore al suo primo elemento (infatti de-referenziandolo (--> *a) dovresti ottenere il valore del suo primo elemento).
    Tu sai che un puntatore rappresenta un indirizzo di memoria. Ora, fare un if in cui si confrontano due puntatori vale a dire mettere a confronto due indirizzo di memoria. Quindi if(b>a) non sta per "se l'array b è più grande dell'array a" bensì "l'indirizzo di memoria 0x6dfef0 è più grande dell'indirizzo 0x6dfefc" (gli indirizzi li ho sparati a caso...)

    Per fare ciò che dici tu dovresti fare una cosa del genere:
    lunghezzaA=sizeof(a)/sizeof(int); // ottieni così la lunghezza dell'array a
    lunghezzaB=sizeof(b)/sizeof(int); // ottieni così la lunghezza dell'array b
    if(lunghezzaB>lunghezzaA)
    ...
    Una cosa in più! Grazie mille, per il resto il programma è giusto o ha bisogno di una modifica?
  • Re: Unione dei vettori + ordinamento

    Dando un'occhiata veloce migliorerei questo: nella condizione del do...while (while(ca!=5 && cb!=5)), anzicchè mettere il diverso (!=) ci metterei un minore (<) che nella fattispecie non ti cambia nulla ma bisogna essere più precisi, perchè in altre eventualità se confondi il '!=' col '<' potresti avere qualche risultato inaspettato...
    Per il resto, testalo e se il tutto va come ti sei prefissato allora sei a posto. Il consiglio è quello di testare nei modi più disparati come per cercare il pelo nell'uovo e se anche così va tutto ok, vuol dire che hai fatto un buon lavoro!
  • Re: Unione dei vettori + ordinamento

    2_3rr0r5 ha scritto:


    Dando un'occhiata veloce migliorerei questo: nella condizione del do...while (while(ca!=5 && cb!=5)), anzicchè mettere il diverso (!=) ci metterei un minore (<) che nella fattispecie non ti cambia nulla ma bisogna essere più precisi, perchè in altre eventualità se confondi il '!=' col '<' potresti avere qualche risultato inaspettato...
    Per il resto, testalo e se il tutto va come ti sei prefissato allora sei a posto. Il consiglio è quello di testare nei modi più disparati come per cercare il pelo nell'uovo e se anche così va tutto ok, vuol dire che hai fatto un buon lavoro!
    Allora seguendo il tuo consiglio di prima ho creato questa parte di codice:
     la=sizeof(a);
     lb=sizeof(b);
     for(i=0;i<=c;i++)
        {if(lb>la)
           {v[i]=b[cb];
            cb++;
            lb--;
           }
        else
           {v[i]=a[ca];
            ca++;
            la--
           }
        }
    Tuttavia ho notato che "Sizeof" non mi legge quante variabili ci sono dentro. Ma direttamente la lunghezza del vettore. Quindi questo mi causa un errore nell'ultima variabile che vado ad inserire:

    Es:

    2 3 6 1 4 7 12 10

    Oltre a mettermeli come li scrivo (senza mettere prima i pari e poi i dispari o viceversa [come appunto dovrebbe fare]) me li mette nello stesso ordine sostituendo al 10 un numero randomico preso dalla RAM
  • Re: Unione dei vettori + ordinamento

    krastykrab1 ha scritto:


    2_3rr0r5 ha scritto:


    Dando un'occhiata veloce migliorerei questo: nella condizione del do...while (while(ca!=5 && cb!=5)), anzicchè mettere il diverso (!=) ci metterei un minore (<) che nella fattispecie non ti cambia nulla ma bisogna essere più precisi, perchè in altre eventualità se confondi il '!=' col '<' potresti avere qualche risultato inaspettato...
    Per il resto, testalo e se il tutto va come ti sei prefissato allora sei a posto. Il consiglio è quello di testare nei modi più disparati come per cercare il pelo nell'uovo e se anche così va tutto ok, vuol dire che hai fatto un buon lavoro!
    Allora seguendo il tuo consiglio di prima ho creato questa parte di codice:
     la=sizeof(a);
     lb=sizeof(b);
     for(i=0;i<=c;i++)
        {if(lb>la)
           {v[i]=b[cb];
            cb++;
            lb--;
           }
        else
           {v[i]=a[ca];
            ca++;
            la--
           }
        }
    Tuttavia ho notato che "Sizeof" non mi legge quante variabili ci sono dentro. Ma direttamente la lunghezza del vettore. Quindi questo mi causa un errore nell'ultima variabile che vado ad inserire:

    Es:

    2 3 6 1 4 7 12 10

    Oltre a mettermeli come li scrivo (senza mettere prima i pari e poi i dispari o viceversa [come appunto dovrebbe fare]) me li mette nello stesso ordine sostituendo al 10 un numero randomico preso dalla RAM
    sizeof non ritorna mai il numero di elementi nell'array !

    Explanation
    1) Returns size in bytes of the object representation of type.
    2) Returns size in bytes of the object representation of the type that would be returned by expression, if evaluated.
    Se vuoi sapere quanti elementi ci sono nell'array potresti usare fare una cosa del genere
    
    std::size_t array_size=sizeof(my_array)/sizeof(my_array_type);
    
    opure se vuoi una cosa generica
    
    template<typename T,std::size_t N>
    std::size_t get_array_size(T (&)[N])
    {
    	return N;
    }
    
    Comunque entrambi i modi ritornano i numero di elementi che l'array può contenere non il numero di elementi effettivamente inseriti, se vuoi esattamente il numero di elementi inseriti o dovresti tenere traccia tu oppure dovresti usare std::vector.
    Per quanto riguarda il tuo codice ci sono altre cose che secondo me non vanno bene.
    1) I VLA non sono standard
    
    int v[c];
    
    Se compili il seguente codice sia con clang sia con gcc ti farà vedere dei warning
    2) Non puoi usare gli array cosi
    
    if(b>a)
    
    Non ha nessun senso la riga precedente perché stai confrontando il primo indirizzi degli array, comunque penso che questo è un errore di distrazione forse volevi scrivere b[cb]>a[ca]
    3) Dovresti dare nomi un po' più significativi alle tue variabli
    4) Il raggruppamento di variabili è una cosa di C, ti consiglio di dichiarare una variabile soltanto quando hai bisogno di essa in C++
    5) Quando dichiari una variabile dovresti inizializzarla subito
    
    int a; //Non è sbagliato ma personalmente lo trovo orrendo
    a=0;
    int a=0;
    [code]
    Nel tuo caso ci sono più variabili dello stesso tipo quindi puoi anche splittargli in più righe
    [code]
      int ca=0, cb=0, c=0;
        int n=0, i=0, x=0;
        int a[5]={0,0,0,0,0}, b[5]={0,0,0,0,0};
        int m=0, temp=0, j=0, mini=0;
    
    Per quanto riguarda il funzionamento secondo me sono gli ultimi due cicli che ti fanno sbagliare ( non posso dirti esattamente dove, perché ho difficoltà a leggere il tuo codice), da come l'hai descritto l'algoritmo sembra un merge sort, quindi ti consiglio di cercarlo su google, ci sono tantissimi esempi sia in inglese sia in italiano.
  • Re: Unione dei vettori + ordinamento

    Sizeof non ti serve a nulla in questo codice.

    Quanti valori sono contenuti nei vettori lo sai perché li hai contati ... il numero sta in ca e in cb alla fine dell'input.
    Peccato che tu azzeri quelle variabili, cosa sbagliata, in quanto dovresti utilizzarle proprio per sapere quanti sono i valori che sono stati inseriti.
  • Re: Unione dei vettori + ordinamento

    krastykrab1 ha scritto:


    2_3rr0r5 ha scritto:


    Dando un'occhiata veloce migliorerei questo: nella condizione del do...while (while(ca!=5 && cb!=5)), anzicchè mettere il diverso (!=) ci metterei un minore (<) che nella fattispecie non ti cambia nulla ma bisogna essere più precisi, perchè in altre eventualità se confondi il '!=' col '<' potresti avere qualche risultato inaspettato...
    Per il resto, testalo e se il tutto va come ti sei prefissato allora sei a posto. Il consiglio è quello di testare nei modi più disparati come per cercare il pelo nell'uovo e se anche così va tutto ok, vuol dire che hai fatto un buon lavoro!
    Allora seguendo il tuo consiglio di prima ho creato questa parte di codice:
     la=sizeof(a);
     lb=sizeof(b);
     for(i=0;i<=c;i++)
        {if(lb>la)
           {v[i]=b[cb];
            cb++;
            lb--;
           }
        else
           {v[i]=a[ca];
            ca++;
            la--
           }
        }
    Tuttavia ho notato che "Sizeof" non mi legge quante variabili ci sono dentro. Ma direttamente la lunghezza del vettore. Quindi questo mi causa un errore nell'ultima variabile che vado ad inserire:

    Es:

    2 3 6 1 4 7 12 10

    Oltre a mettermeli come li scrivo (senza mettere prima i pari e poi i dispari o viceversa [come appunto dovrebbe fare]) me li mette nello stesso ordine sostituendo al 10 un numero randomico preso dalla RAM
    Io in realtà ti avevo consicgliato di fare così:
    lunghezzaA=sizeof(a)/sizeof(int);
    non così:
    lunghezzaA=sizeof(a);


    La funzione sizeof() ti conta quanti bytes è lungo un tipo di dato, una variabile o un'oggetto, per cui sizeof(a) ti dice quanti bytes contiene l'array a
    Es: int a[100] conterrebbe 400 byte. Questo però vale solo dove il tipo int "pesa" 4 bytes e anche se tu non hai ancora inserito nulla perchè lo spazio viene già allocato (allocazione statica dalla memoria).
    Perchè 400 bytes?
    Perchè ci sono 100 elementi, ognuno "pesa" 4 bytes: 4 bytes*100 elementi=400 bytes.

    Detto questo, facendo la "formula inversa", se io divido la lunghezza (in bytes) dell'array (sizeof(a)) per la lunghezza di ogni elemento (quindi sizeof(int)), ottengo come risultati il numero di elementi che contiene l'array. Ritornando ai numeri:
    lunghezzaA=sizeof(a)/sizeof(int)
    è uguale a:
    lunghezzaA=400/4=100
    dove come risultato di sizeof(int) ho messo 4, visto che nella maggior parte dei casi una variabile di tipo int "pesa" 4 bytes, ma noi per essere precisi, nella formula scriviamo sizeof(int) perchè la dimensione di un intero potrebbe cambiare tra una piattaforma e un'altra.
    Ovviamente dividiamo per sizeof(int) perchè stiamo trattando un array di int, nel caso fosse un array di char, avremmo diviso per sizeof(char)

    se tu invece scrivi lunghezzaA=sizeof(a), avrai in lunghezzaA il numero di bytes di a, cioè 400, ma noi abbiamo detto nel nostro esempio che a contiene 100 ecco perchè quella divisione (/sizeof(int)) è importante.

    Concludo dicendo che non avendo letto il codice, almeno non con molta attenzione, non avevo notato che, come sostiene oregon, quest'operazione è superflua perchè il numero di elementi tu già ce l'hai nelle varibili ca e cb, però quello che ti ho suggerito potrebbe aiutarti in futuro.
    Spero di essere stato chiaro e di non averti confuso ancora di più
Devi accedere o registrarti per scrivere nel forum
9 risposte