Domanda Risolto Esercizio c++

Stato
Discussione chiusa ad ulteriori risposte.

NeomagusPr0

Utente Electrum
3 Settembre 2012
276
18
48
115
Salve ragazzi, come da titolo avrei problemi nello svolgimento del seguente esercizio:

Seguendo i principi della programmazione strutturata e della modularità, si sviluppi un programma in C/C++ che:
- richieda all’utente di inserire da tastiera due vettori di numeri interi di dimensione pari al massimo a 30;
- richieda all'utente, mediante un sottoprogramma, di calcolare in un terzo vettore, la somma dei numeri dispari dei due vettori;
- visualizzi a video il risultato ottenuto.

Per il primo punto non ho problemi, mentre per il secondo ho provato ad impostare senza sottoprogramma, non mi da errori di compilazione ma ovviamente il risultato non è cio che mi aspetto. L' Grazie in anticipo per suggerimenti.

C++:
#include <iostream>
#define R_MAX 30

using namespace std;

typedef int vettore[R_MAX];

int main (){
   
    int dim_r, dim_c;
    vettore v1,v2,v3;
   
    cout << "Inserire dimensione primo vettore" ;
    cin >> dim_r;
   
    cout << "Inserire dimensione secondo vettore ";
    cin >> dim_c;
   
    for (int i = 0; i < dim_r; i++){
       
        cout << "v1[" << i+1<< "]" ;
        cin  >> v1[i];
        }
        for (int i = 0; i < dim_c; i++){
            cout << "v2[" << i+1 << "]" ;
        cin  >> v2[i];
    }
       
        for (int i = 0; i < 10; i++){
            if (v1[i]%2 !=0 )
            if (v2[i]%2 !=0)
           
            v3[i]=v1[i]+v2[i];
           
            cout << v3[i]<< "La somma dei numeri dispari e' : " ;
        }
       
        return 0;
}
 
A prima vista noto un errore: l'esercizio richiede espressamente che i vettori non siano più lunghi di 30 elementi. Tu lasci inserire una dimensione ma poi non la controlli, dando tuttavia ai vettori una dimensione massima di 30 elementi. Rischi di andare "out of bounds" quando vengono inseriti i valori. Dovresti richiedere le dimensioni e assicurarti che non superino 30 elementi.

Nell'ultimo for vedo un errore: scorri sino a 10 elementi, ma in realtà non sai quanti sono: la dimensione massima dovrebbe essere il massimo tra dim_r e dim_c. In realtà, se entrambe le posizioni devono avere un elemento dispari, puoi anche considerare la dimensione minima e non quella massima.

Se non sono entrambi dispari, dovresti settare l'indice di v3 a 0, oppure "saltarlo" (in tal caso ti serve un contatore solo per v3).
Poi non sono sicuro, ma è possibile che il testo voglia farti fare un ciclo solo su v3 per la stampa (altrimenti per come lo hai scritto diventa inutile avere un vettore che contenga i risultati, in quanto potresti stampare solo v1[i] + v2[i]).
 
Ultima modifica:
Per il primo quindi mi converrebbe mettere un controllo come un do -while o un booleano dopo aver espresso le dimensioni dei due vettori, giusto? EDIT, ho risolto il controllo con due do-while quando mi chiede di inserire dimensione del vettore, se metto più di 30 mi richiede la dimensione.

Per il secondo punto ho capito, ho fatto un errore di distrazione perchè mi ero dimenticato fosse 30 la dimensione massima (stavo facendo un esercizio simile con dimensione massima 10 ).

Per quanto riguarda il terzo punto, ho provato a settare un indice somma_dispari =0 prima dell'ultimo for, l'ho impostato con dimensione massima di 30 e ho scritto somma_dispari come somma dei due vettori, rimanendo invariati gli ultimi due if, ma funge.

C++:
    int somma_dispari = 0;
       
        for (int i = 0; i < 30; i++){
            if (v1[i]%2 !=0 )
            if (v2[i]%2 !=0)
           
            somma_dispari =v1[i]+v2[i];
           
            cout << "La somma dei numeri dispari e' : " << somma_dispari << endl ;
        }
 
In realtà 30 come valore non è corretto, perchè tu hai al massimo 30 elementi. Quindi v1 potrebbe averne 10 e v2 15, per esempio.
Inoltre, le posizioni comprese tra dim_r o dim_c e 30 che valore hanno? Devi assicurarti che valgano 0 se fai in quel modo (ovvero scorrere 30 elementi), altrimenti ti trovi sicuramente valori sporchi (sempre se non fai come dico qui sotto).
Quindi ricapitolando: puoi anche scorrere 30 elementi (anche se sarebbe corretto scorrere sino alla dimensione massima inserita), ma assicurati che siano a 0; dovresti assicurarti di inizializzarli a 0 in entrambi i casi comunque, sempre se non vuoi fare un controllo in più sulla lunghezza massima.

Questo è il contenuto di v1, nel mio caso, se non inizializzo:
Codice:
V1: 0 0 4200085 0 0 0 0 0 0 0 0 0 6421952 0 4201421 0 4201248 0 4200002 0 7018144 0 0 0 4194304 0 0 2 6422000 0

La variabile che hai dichiarato non dovresti usarla; tu devi usare un vettore, era giusto quello che facevi prima.

Al posto tuo eviterei quel typedef con la definizione globale. Piuttosto, farei così, almeno inizializzi i vettori a 0:
C:
    int v1[R_MAX] = {0}, 
        v2[R_MAX] = {0}, 
        v3[R_MAX] = {0};

Questo è sempre v1:
Codice:
V1: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 
Ho provato a fare in questo modo: ho tolto il typedef dichiarando i 3 vettori come mi hai consigliato e ho impostato come dim_r (cioè la dimensione del primo vettore ) la dimensione massima che possono avere. A parte che adesso quando stampo i risultati, mi esce 0, ma penso che sto sbagliando qualcosa (anzi, sicuramente ) quando dichiaro la dimensione del 3 vettore che contiene le somme dei numeri dispari.


C++:
#define R_MAX 30


using namespace std;


int main (){
    
    int dim_r, dim_c;
    int v1[R_MAX]= {0};
    int v2 [R_MAX] = {0};
    int v3 [R_MAX] = {0};
    dim_r = R_MAX;
    
    do {
    cout << "Inserire dimensione primo vettore" ;
    cin >> dim_r;
   }while (dim_r > 30);
  
   do{
    cout << "Inserire dimensione secondo vettore ";
    cin >> dim_c;
    }while (dim_c > 30);

    for (int i = 0; i < dim_r; i++){
        
        cout << "v1[" << i+1<< "]" ;
        cin  >> v1[i];
        }
        for (int i = 0; i < dim_c; i++){
            cout << "v2[" << i+1 << "]" ;
        cin  >> v2[i];
    }
    
        
        for (int i = 0; i < dim_r ; i++){
            if (v1[i]%2 !=0 )
            if (v2[i]%2 !=0)
            
            v3[i]=v1[i]+v2 [i];
        }
        
            cout << "La somma dei numeri dispari e' : " << v3[dim_r] << endl ;
        
        
        return 0;
}
 
Stai sbagliando l'accesso al vettore v3 quando stampi:
C:
            cout << "La somma dei numeri dispari e' : " << v3[dim_r] << endl ;

Dovresti fare un nuovo ciclo dove scorri tutto l'array. In alternativa, puoi fare come facevi prima, e stampare direttamente (anche se diciamo che l'array perderebbe di significato in quanto non utilizzato).

Non so poi come devono essere disposti gli elementi nel terzo vettore: se devi avere solo i numeri dispari, ti conviene usare un altro indice per il vettore 3, così avrai solo gli elementi dispari, e non anche le posizioni vuote (che saranno a 0).
 
Ho provato a fare cosi ma penso di essere entrato nel pallone più assoluto, non mi vengono altre idee.

Si, nel terzo vettore devo avere solo la somma dei numeri dispari dei primi due vettori.
Ho provato a fare anche come prima che introducevo int somma_dispari =0, scrivevo il ciclo for e dopo gli if scrivevo che somma_dispari = somma dei due vettori, ma continua ad uscirmi 0.

C++:
    for (int i=0; i< dim_r; i++)
           
            cout <<   "La somma dei numeri dispari e' : "  << v3[i] << endl ;

PS: scusami del disturbo
 
e ho impostato come dim_r (cioè la dimensione del primo vettore ) la dimensione massima che possono avere

Mi ero perso questo: l'assegnazione non serve, in quanto la vai a sovrascrivere non appena leggi il valore per dim_r.

Questa è la soluzione "migliore":

C:
    int v3_counter = 0;
    int len_max = max(dim_r, dim_c);
    for(int i = 0; i < len_max; i++){
        if(v1[i]%2 !=0 && v2[i]%2 !=0)
              v3[v3_counter++]=v1[i]+v2[i];  
    }
  
    for(int i=0; i<v3_counter; i++)
        cout << "Somma indice "<< (i+1) <<" : " << v3[i] << endl;

Così se inserisci come v1 3 elementi e come v2 5 elementi, len_max sarà uguale a 5 (e non 30).
Chiaramente nella stampa in questo caso l'indice "I" farà riferimento alla posizione nel vettore 3 e non ai vettori v1/v2, poichè non lasci "buchi".

Esempio di output:
Codice:
v1[1]1
v1[2]2
v1[3]3
v2[1]1
v2[2]2
v2[3]3
v2[4]4
v2[5]5
Somma indice 1 : 2
Somma indice 2 : 6

Se vuoi mantenere gli indici originali puoi fare così:

C:
    int len_max = max(dim_r, dim_c);
    for(int i = 0; i < len_max; i++){
        if(v1[i]%2 !=0 && v2[i]%2 !=0)
              v3[i]=v1[i]+v2[i];  
    }
  
    for(int i=0; i<len_max; i++)
        cout << "Somma indice "<< (i+1) <<" : " << v3[i] << endl;

Esempio di output:

Codice:
v1[1]1
v1[2]2
v1[3]3
v2[1]1
v2[2]2
v2[3]3
v2[4]4
v2[5]5
Somma indice 1 : 2
Somma indice 2 : 0
Somma indice 3 : 6
Somma indice 4 : 0
Somma indice 5 : 0

Ovviamente puoi anche stampare solo le posizioni con valore != 0.

Ricapitolando, questo è il codice completo:

C:
#include <iostream>

#define R_MAX 30

using namespace std;


int main (){
  
    int dim_r, dim_c;
    int v1[R_MAX] = {0},
        v2[R_MAX] = {0},
        v3[R_MAX] = {0};
       
    do {
        cout << "Inserire dimensione primo vettore" ;
        cin >> dim_r;
    }while (dim_r > 30);
 
    do{
        cout << "Inserire dimensione secondo vettore ";
        cin >> dim_c;
    }while (dim_c > 30);
  
    cout << endl;
   
    for (int i = 0; i < dim_r; i++){
      
        cout << "v1[" << i+1<< "]" ;
        cin  >> v1[i];
    }
   
    for (int i = 0; i < dim_c; i++){
        cout << "v2[" << i+1 << "]" ;
        cin  >> v2[i];
    }
      

    int len_max = max(dim_r, dim_c);
    for(int i = 0; i < len_max; i++){
        if(v1[i]%2 !=0 && v2[i]%2 !=0)
              v3[i]=v1[i]+v2[i];   
    }
   
    for(int i=0; i<len_max; i++)
        cout << "Somma indice "<< (i+1) <<" : " << v3[i] << endl;
      
    return 0;
}
 
Ho provato a fare in ambo le soluzioni, solo che il codice completo mi da come somma indici sempre 0, mentre per il secondo metodo, usando il contatore per il terzo vettore , mi termina il programma dopo l'inserimento dei valori dei primi due vettori. Ho provato sia con DEV che sul compilatore online.
 
DEV non sarebbe nemmeno da considerare. Usa MinGw se sei sotto Windows, oppure il compilatore di Microsoft.
Io non ho problemi con quanto mostrato li sopra, nè con MinGw nè con MSVC.

Che valori hai inserito in input usando il codice completo?
 
C++:
iostream>

#define R_MAX 30

using namespace std;


int main (){
 
    int dim_r, dim_c;
    int v1[R_MAX] = {0},
        v2[R_MAX] = {0},
        v3[R_MAX] = {0};
      
    do {
        cout << "Inserire dimensione primo vettore" ;
        cin >> dim_r;
    }while (dim_r > 30);
 
    do{
        cout << "Inserire dimensione secondo vettore ";
        cin >> dim_c;
    }while (dim_c > 30);
 
    
  
    for (int i = 0; i < dim_r; i++){
      
        cout << "v1[" << i+1<< "]" ;
        cin  >> v1[i];
    }
  
    for (int i = 0; i < dim_c; i++){
        cout << "v2[" << i+1 << "]" ;
        cin  >> v2[i];
    }
      

    int v3_counter = 0;
    int len_max = max(dim_r, dim_c);
    for(int i = 0; i < len_max; i++){
        if(v1[i]%2 !=0 && v2[i]%2 !=0)
              v3[v3_counter++]=v1[i]+v2[i]; 
    }
 
    for(int i=0; i<v3_counter; i++)
        cout << "Somma indice "<< (i+1) <<" : " << v3[i] << endl;
  
      
    return 0;
}



Ho provato a copiare e incollare il codice completo in toto e mi da la somma pari a 0, mentre usando questo altro codice , il programma termina dopo l'inserimento dei valori dei due vettori. Ho provato ad usare Visual Studio ma da lo stesso problema, MinGw non riesco a scaricarlo.
 
Ad esempio inserisco come dimensione dei due vettori iniziali 3 e 3 e poi inserisco numeri a caso. Ho provato anche con dimensioni diverse e numeri diversi ma non cambia.
 
Si ma posta gli input esatti... Mi sembra strano che il medesimo codie mi funzioni senza problemi e a te no, soprattutto visto che il codice non presenta errori.

Prova ad esempio con: v1 = 3 e v2 = 5.

Poi inserisci: v1 = 1, 2, 3 e v2 = 1, 2, 3, 4, 5.

Codice:
Inserire dimensione primo vettore 3
Inserire dimensione secondo vettore 5

v1[1]1
v1[2]2
v1[3]3
v2[1]1
v2[2]2
v2[3]3
v2[4]4
v2[5]5
Somma indice 1 : 2
Somma indice 2 : 6
 
Ultima modifica:
Ad esempio se provo:

Inserire dimensione primo vettore 3
Inserire dimensione secondo vettore 3
v1[1]1
v1[2]2
v1[3]3
v2[1]6
v2[2]5
v2[3]4

Se per esempio utilizzo questi input, il programma termina qui. Se invece utilizzo i tuoi input, oppure ad esempio :

Inserire dimensione primo vettore 3
Inserire dimensione secondo vettore 3
v1[1]1
v1[2]2
v1[3]3
v2[1]3
v2[2]2
v2[3]1

Somma indice 1 : 4
Somma indice 2 : 4

va tutto liscio.

EDIT: Ho notato che se ad esempio utilizzo 1 4 7 e 7 4 1 come numeri del vettore (supponendo sempre che i vettori abbiano dimensione 3 e 3) oppure una sequenza di numeri ordinata e al contrario (2 5 8 e 8 5 2, 9 6 3 e 3 6 9 ) il programma funziona alla perfezione, mentre se utilizzo ad esempio 2 5 8 e 9 6 3 , mi termina il programma .
 
Bhe, per forza... :D

Guarda la condizione per contare i numeri dispari: entrambi alla i-esima posizione devono essere dispari.
Codice:
v1[1]1
v1[2]2
v1[3]3
v2[1]6
v2[2]5
v2[3]4

Qui hai v1[1] e v2[1] che sono 1 pari e uno dispari, quindi il counter non viene incrementato.
Poi hai v1[2] e v2[2] che sono anche qui uno pari e l'altro dispari, quindi non viene incrementato.
Poi in ultimo hai v1[3] e v2[3] che sono uno pari e uno dispari, quindi non viene incrementato.

La condizione dell'if vuole che entrambi siano dispari (idem nel tuo codice, quando usavi 2 if distinti).

Vale la pena che al termine aggiungi un "if" dove verifichi se il contatore è a 0; se è a 0 non ci sono coppie di dispari, quindi potresti mostrare un avviso.
 
  • Mi piace
Reazioni: NeomagusPr0
E se invece ad esempio, nel terzo vettore vorrei visualizzare la somma di tutti gli elementi dispari indistintamente dall'indice?
Nel senso, considerando sempre due vettori di dimensione 3 per semplicità:

v1[1]1
v1[2]2
v1[3]3
v2[1]6
v2[2]5
v2[3]4

e visualizzo come risultato 9 (1 +3 +5), cioè la somma di tutti i numeri dispari, indipendentemente dalla loro posizione.
Scusami sempre, ti ringrazio per il tempo che stai perdendo, sorry.
 
Figurati, il forum è qui anche per questo.

In quel caso hai la somma totale, quindi non ti serve il terzo vettore, sempre se non vuoi memorizzarli tutti nell'array v3. Ma in tal caso dovresti avere o un v3 più grande (ipoteticamente il doppio, in caso v1 e v2 avessero entrambi 30 elementi) oppure in caso v1[i] e v2[i] fossero dispari, la somma di questi in v3[i].

Da un punto di vista dell'algoritmo dovresti separare gli if e non innestarli, e aggiungere il nuovo elemento (se dispari) incrementando il contatore.
 
  • Mi piace
Reazioni: NeomagusPr0
C++:
#include <iostream>
#define R_MAX 30

using namespace std;


int main (){
 
    int dim_r, dim_c;
    int v1[R_MAX] = {0};
    int v2[R_MAX] = {0};
      
    do {
        cout << "Inserire dimensione primo vettore : " ;
        cin >> dim_r;
    }while (dim_r > 30);
 
    do{
        cout << "Inserire dimensione secondo vettore : ";
        cin >> dim_c;
    }while (dim_c > 30);
 
    
  
    for (int i = 0; i < dim_r; i++){
      
        cout << "v1[" << i+1<< "]" ;
        cin  >> v1[i];
    }
  
    for (int i = 0; i < dim_c; i++){
        cout << "v2[" << i+1 << "]" ;
        cin  >> v2[i];
    }
      
    int somma_num_dispari = 0;
    int len_max = max(dim_r, dim_c);
        for(int i = 0; i < len_max; i++){
           if(v1[i] % 2 != 0)
            somma_num_dispari += v1[i];
        }
        
    int somma_num_dispari_ = 0;
    for(int i = 0; i < len_max; i++){
           if(v2[i] % 2 != 0)
            somma_num_dispari_ += v2[i];
        }
        
        int somma =0;
        for (int i = 0; i < len_max; i++){
            somma= somma_num_dispari + somma_num_dispari_;
            
        }
         cout << "La somma dei numeri dispari e' : " << somma << endl;
          
          return 0;
    }

Ho finalmente capito come fare, i tuoi ultimi consigli sono stati fondamentali. Ho fatto separatamente le somme e poi ho unito il tutto senza utilizzare il terzo vettore. Grazie mille per i suggerimenti e l'aiuto, non sarei riuscito altrimenti :p
 
Di nulla, comunque fai attenzione agli indici, perchè stai sbagliando la condizione di uno dei for. len_max contiene la lunghezza maggiore.
Se vuoi solo la somma totale puoi scriverlo così comunque:

C:
    int somma_num_dispari = 0;
    for(int i = 0; i < dim_r; i++){
       if(v1[i] % 2 != 0)
        somma_num_dispari += v1[i];
    }
        
    for(int i = 0; i < dim_c; i++){
       if(v2[i] % 2 != 0)
        somma_num_dispari += v2[i];
    }
    
    cout << "La somma dei numeri dispari e' : " << somma_num_dispari << endl;

Chiaramente, se volessi risparmiarti qualche for, puoi anche inserire gli if già nei cicli sopra (dove leggi l'input).

Un'altra soluzione ancora?
C:
    int somma_num_dispari = 0;
    int len_max = max(dim_r, dim_c);
    for(int i = 0; i < len_max; i++){
        if(i < dim_r && (v1[i] % 2 != 0))
            somma_num_dispari += v1[i];       
    
        if(i < dim_c && (v2[i] % 2 != 0))
            somma_num_dispari += v2[i];
    }

Il controllo ulteriore sull'indice è per evitare di sforare andando a leggere una posizione che non esiste; in questo caso ovviamente visto che ci sono 30 elementi già allocati non è un problema, ma quando allocherai degli array con dimensioni esatte, allora farà la differenza.
 
  • Mi piace
Reazioni: NeomagusPr0
Ho modificato il programma come mi hai consigliato nell'ultimo messaggio, fatto cosi sembra anche più pulito di come l'ho scritto io. Ti ringrazio tanto nuovamente, sei stato utilissimo.
 
Stato
Discussione chiusa ad ulteriori risposte.