[C++] esercizio ok?
Devo fare l'esame di informatica per ingegneria meccanica e sto cercando di risolvere alcuni esercizi.
"Siano dati in ingresso due vettori V1 e V2 di numeri interi. Si supponga che entrambi i vettori siano disordinati. Scrivere un programma (in C++) che identifichi la più lunga sequenza di elementi ordinati del vettore V1 (denominata S1) e la più lunga sequenza di elementi ordinati del vettore V2 (denominata S2). Si provveda poi a scambiare tali sequenze: la sequenza S1 trovata nel vettore V1 deve essere inserita nel vettore V2 al posto della sequenza S2 e viceversa. Stampare infine i vettori V1 e V2."
Io l'ho risolto così:
Pare che funzioni, voi che dite? Grazie
"Siano dati in ingresso due vettori V1 e V2 di numeri interi. Si supponga che entrambi i vettori siano disordinati. Scrivere un programma (in C++) che identifichi la più lunga sequenza di elementi ordinati del vettore V1 (denominata S1) e la più lunga sequenza di elementi ordinati del vettore V2 (denominata S2). Si provveda poi a scambiare tali sequenze: la sequenza S1 trovata nel vettore V1 deve essere inserita nel vettore V2 al posto della sequenza S2 e viceversa. Stampare infine i vettori V1 e V2."
Io l'ho risolto così:
#include <iostream> using namespace std; int main() { cout<<"Scegliere la dimensione del primo vettore:\n"; int dim1; int dim2; cin>>dim1; cout<<"Scegliere la dimensione del secondo vettore:\n"; cin>>dim2; int vett1[dim1]; int vett2[dim2]; int i; for (i=0;i<dim1;i++) {cout<<"Inserisci l'elemento numero "<<i+1<<" del primo vettore:\n"; cin>>vett1[i]; } for (i=0;i<dim2;i++) {cout<<"Inserisci l'elemento numero "<<i+1<<" del secondo vettore:\n"; cin>>vett2[i]; } cout<<"Il primo vettore è:\n"; for(i=0;i<dim1;i++) {cout<<" "<<vett1[i];} cout<<"\nIl secondo vettore è:\n"; for(i=0;i<dim2;i++) {cout<<" "<<vett2[i];} //introduco il vettore lunghezza1 e indpar1 in cui memorizzare le lunghezze e gli indici di partenza delle serie trovate int j1=-1; int lunghezza1[dim1]; int uno1=1; int k1=0; int indpar1[dim1]; //azzero i vettori lunghezza1 e indpar1 for(i=0;i<dim1;i++) {lunghezza1[i]=0;} for(i=0;i<dim1;i++) {indpar1[i]=0;} //memorizzazione di lunghezze e indici nelle componenti dei vettori for(i=1;i<dim1;i++) { if(vett1[i-1]<vett1[i]) {j1++; lunghezza1[j1]=++uno1; indpar1[j1]=k1;} else {uno1=1; k1=i;} } //calcolo dell'elemento massimo e sua posizione int massimo1; int posmax1=0; massimo1=lunghezza1[0]; for(i=1;i<dim1;i++) { if(massimo1<lunghezza1[i]) {massimo1=lunghezza1[i]; posmax1=i;} } cout<<"\nLa sequenza crescente più lunga del primo vettore ha lunghezza "<<massimo1<<" e parte dalla posizione "<<indpar1[posmax1]+1; cout<<"\nEssa è:\n"; for(i=indpar1[posmax1];i<indpar1[posmax1]+massimo1;i++) {cout<<" "<<vett1[i];} //Faccio la stessa cosa per il secondo vettore int j2=-1; int lunghezza2[dim2]; int uno2=1; int k2=0; int indpar2[dim2]; for(i=0;i<dim2;i++) {lunghezza2[i]=0;} for(i=0;i<dim2;i++) {indpar2[i]=0;} for(i=1;i<dim2;i++) { if(vett2[i-1]<vett2[i]) {j2++; lunghezza2[j2]=++uno2; indpar2[j2]=k2;} else {uno2=1; k2=i;} } int massimo2; int posmax2=0; massimo2=lunghezza2[0]; for(i=1;i<dim2;i++) { if(massimo2<lunghezza2[i]) {massimo2=lunghezza2[i]; posmax2=i;} } cout<<"\nLa sequenza crescente più lunga del secondo vettore ha lunghezza "<<massimo2<<" e parte dalla posizione "<<indpar2[posmax2]+1; cout<<"\nEssa è:\n"; for(i=indpar2[posmax2];i<indpar2[posmax2]+massimo2;i++) {cout<<" "<<vett2[i];} //scambio le sequenze ordinate e mostro i risultati cout<<"\nSostituendo la sequenza ordinata del primo vettore con quella del secondo, il primo vettore diventa:\n"; for(i=0;i<indpar1[posmax1];i++) {cout<<" "<<vett1[i];} for(i=indpar2[posmax2];i<indpar2[posmax2]+massimo2;i++) {cout<<" "<<vett2[i];} for(i=indpar1[posmax1]+massimo1;i<dim1;i++) {cout<<" "<<vett1[i];} cout<<"\nSostituendo la sequenza ordinata del secondo vettore con quella del primo, il secondo vettore diventa:\n"; for(i=0;i<indpar2[posmax2];i++) {cout<<" "<<vett2[i];} for(i=indpar1[posmax1];i<indpar1[posmax1]+massimo1;i++) {cout<<" "<<vett1[i];} for(i=indpar2[posmax2]+massimo2;i<dim2;i++) {cout<<" "<<vett2[i];} }
Pare che funzioni, voi che dite? Grazie
Risposte
La colpa è certamente del tuo professore, ma il codice che hai scritto fa uso di estensioni disponibili in un particolare compilatore che non sono in generale portabili ad altri compilatori in quanto al di fuori dello standard. In effetti è possibile che il codice non compili neanche nei compilatori che supportano tale estensione a seconda della scelta degli argomenti passati al compilatore.
La dimensione di un array DEVE essere una costante a tempo di compilazione in base allo standard. Non può essere una variabile come nel tuo codice. Oltretutto non stai neanche verificando che i valori passati dall'utente abbiano senso. Cosa succede nel tuo codice se l'utente inserisce un valore negativo? Cosa succede se inserisce un valore molto grande?
Nel corso ti sono state insegnate le funzioni? Ci sono un sacco di ripetizioni nel tuo codice che andrebbero probabilmente estratte in funzioni.
Per il resto ad una occhiata veloce mi sembra corretto.
La dimensione di un array DEVE essere una costante a tempo di compilazione in base allo standard. Non può essere una variabile come nel tuo codice. Oltretutto non stai neanche verificando che i valori passati dall'utente abbiano senso. Cosa succede nel tuo codice se l'utente inserisce un valore negativo? Cosa succede se inserisce un valore molto grande?
Nel corso ti sono state insegnate le funzioni? Ci sono un sacco di ripetizioni nel tuo codice che andrebbero probabilmente estratte in funzioni.
Per il resto ad una occhiata veloce mi sembra corretto.
Non ho seguito il corso, mi servo delle dispense del professore e di un libro di scuola superiore del 1993. Sono agli inizi, non ho mai progammato prima d'ora. Come IDE uso Netbeans.
Il controllo dell'input serve per impedire di invadere zone di memoria al di fuori di quella "prenotata" dal tipo int?
Le funzioni le uso per indicare blocchi di programma ricorrenti in modo da allegerire il codice e velocizzare il lavoro?
Non ho capito invece il discorso sulla dimensione variabile. Quali sarebbero le estensioni di cui parli?
Questo è un esercizio d'esame. Scrivendo il codice che ho postato secondo te sarei risultato sufficiente?
Grazie.
Il controllo dell'input serve per impedire di invadere zone di memoria al di fuori di quella "prenotata" dal tipo int?
Le funzioni le uso per indicare blocchi di programma ricorrenti in modo da allegerire il codice e velocizzare il lavoro?
Non ho capito invece il discorso sulla dimensione variabile. Quali sarebbero le estensioni di cui parli?
Questo è un esercizio d'esame. Scrivendo il codice che ho postato secondo te sarei risultato sufficiente?
Grazie.
Un libro di scuola superiore del 1993 è un reperto storico, non una fonte attendibile su cui studiare. Il primo standard del C++ è successivo a tale data (1997-1998) e il linguaggio è cambiato così tanto che anche un buon libro dei primi anni di questo secolo è molto datato. Quel libro ha quasi 25 anni e nel mondo dell'informatica è un'eternità. Oltretutto i libri di scuola superiore nascono necessariamente già vecchi.
Su Windows l'IDE standard, usato da praticamente ogni società che lavora su tale piattaforma, è Visual Studio. È gratuito per scopi non commerciali e nel caso di società di piccole dimensioni (sia come numero di programmatori che come fatturato). Il compilatore in tale IDE non compila il codice che hai scritto. Richiede infatti, come fa lo standard C++, che la dimensione di un array sia conosciuta in tempo di compilazione. Deve quindi essere un valore numerico o una espressione costante. NON può quindi in particolare essere una variabile letta da console. Ci sono buone ragioni per non permetterlo. La principale risiede nel fatto che non tutti i valori di una variabile intera (anche una senza segno) sono validi. E quelli che sono validi potrebbero dipendere dalla particolare implementazione scelta. Questa estensione dello standard non permette inoltre di gestire facilmente eventuali problemi, cosa possibile nelle alternative. Il controllare tali valori di ingresso ha lo scopo di evitare che valori senza senso (come -1) possano essere inseriti. Questo tipo di funzionalità ha un suo senso in alcune situazioni, ma non in questo. Il metodo corretto sarebbe quello di usare std::vector o l'allocazione dinamica della memoria.
Che tu sia sufficiente o meno dipende dal tuo professore. Probabilmente sì, soprattutto se tali errori sono anche presenti nelle dispense del tuo professore (cosa abbastanza probabile*). Per essere un autodidatta, completamente nuovo alla programmazione, il tuo codice è decisamente buono. Hai chiaramente appreso la parte più difficile della programmazione, quella legata alla definizione di un algoritmo che risolve il problema dato. I problemi del codice sono legati piuttosto alle fonti che hai usato per apprendere il C++, che andrebbero cambiate e aggiornate.
* Sono anni che osservo e mi lamento della cattiva qualità dell'insegnamento del C e C++ ma continuo ad osservare gli stessi errori ripetuti e dispense datate di decenni che vengono ancora riproposte come corrette.
Su Windows l'IDE standard, usato da praticamente ogni società che lavora su tale piattaforma, è Visual Studio. È gratuito per scopi non commerciali e nel caso di società di piccole dimensioni (sia come numero di programmatori che come fatturato). Il compilatore in tale IDE non compila il codice che hai scritto. Richiede infatti, come fa lo standard C++, che la dimensione di un array sia conosciuta in tempo di compilazione. Deve quindi essere un valore numerico o una espressione costante. NON può quindi in particolare essere una variabile letta da console. Ci sono buone ragioni per non permetterlo. La principale risiede nel fatto che non tutti i valori di una variabile intera (anche una senza segno) sono validi. E quelli che sono validi potrebbero dipendere dalla particolare implementazione scelta. Questa estensione dello standard non permette inoltre di gestire facilmente eventuali problemi, cosa possibile nelle alternative. Il controllare tali valori di ingresso ha lo scopo di evitare che valori senza senso (come -1) possano essere inseriti. Questo tipo di funzionalità ha un suo senso in alcune situazioni, ma non in questo. Il metodo corretto sarebbe quello di usare std::vector
Che tu sia sufficiente o meno dipende dal tuo professore. Probabilmente sì, soprattutto se tali errori sono anche presenti nelle dispense del tuo professore (cosa abbastanza probabile*). Per essere un autodidatta, completamente nuovo alla programmazione, il tuo codice è decisamente buono. Hai chiaramente appreso la parte più difficile della programmazione, quella legata alla definizione di un algoritmo che risolve il problema dato. I problemi del codice sono legati piuttosto alle fonti che hai usato per apprendere il C++, che andrebbero cambiate e aggiornate.
* Sono anni che osservo e mi lamento della cattiva qualità dell'insegnamento del C e C++ ma continuo ad osservare gli stessi errori ripetuti e dispense datate di decenni che vengono ancora riproposte come corrette.
Grazie apatriarca. Ci sono ancora cose che non mi sono chiare ma è inutile che faccio domande ora, mi metterò a studiare (la parte sui puntatori mi manca ad esempio) e mi farò vivo fra un pò.
Ti consiglio anche io di usare le funzioni e di utilizzare gli array statici nel modo corretto.
Per quanto riguarda la forma ti consiglio di scrivere il codice in modo indentato e di inserire una sola istruzione per riga.
Dal punto di vista logico (ossia dell'algoritmo) secondo me c'è un ampio margine di miglioramento, nel senso che il problema può essere risolto scorrendo il vettore una sola volta e ricorrendo ad un minor numero di variabili. Per esempio io avrei pensato ad una cosa del genere:
Sembra funzionare, ma credo che anche questo algoritmo possa essere ulteriormente ottimizzato.
Inoltre stando al testo dell'esercizio credo che tu non debba solo mostrare quello che sarebbe il risultato a scambio avvenuto, ma modificare fisicamente i due vettori. Per farlo o utilizzi gli array statici fissando dei limiti per le dimensioni scelte in fase di esecuzione oppure utilizzi l'allocazione dinamica della memoria.
Infine se ti può essere utile ti consiglio il seguente corso di C++ che ritengo molto ben fatto:
http://www.bo.cnr.it/corsi-di-informatica/corsoCstandard/Lezioni/01Indice.html#virtual
Per quanto riguarda la forma ti consiglio di scrivere il codice in modo indentato e di inserire una sola istruzione per riga.
Dal punto di vista logico (ossia dell'algoritmo) secondo me c'è un ampio margine di miglioramento, nel senso che il problema può essere risolto scorrendo il vettore una sola volta e ricorrendo ad un minor numero di variabili. Per esempio io avrei pensato ad una cosa del genere:
#include <iostream> using namespace std; void riempi_vettore(int* v, int dim) { for(int i = 0; i < dim; i++) { cout << "ELEMENTO " << i + 1 << ": "; cin >> v[i]; } } void trova_sequenza(int* v, int dim, int& ind, int& lun) { int ind_, lun_; bool flag = true; for(int i = 0; i < dim - 1; i++) { if(flag) { ind_ = i; lun_ = 1; flag = false; } if(v[i] < v[i + 1]) { ++lun_; if(i < dim - 2) { continue; } } if(lun_ > lun) { ind = ind_; lun = lun_; } flag = true; } } int main() { int v1[100], dim1, ind1, lun1 = 1; cout << "DIMENSIONE VETTORE 1: "; cin >> dim1; riempi_vettore(v1, dim1); trova_sequenza(v1, dim1, ind1, lun1); if(lun1 > 1) { cout << "LA SEQUENZA CRESCENTE PIU' LUNGA E' COSTITUITA DA " << lun1 << " NUMERI E PARTE DALL'ELEMENTO " << ind1 + 1; } else { cout << "NON ESISTE UNA SEQUENZA CRESCENTE"; } }
Sembra funzionare, ma credo che anche questo algoritmo possa essere ulteriormente ottimizzato.
Inoltre stando al testo dell'esercizio credo che tu non debba solo mostrare quello che sarebbe il risultato a scambio avvenuto, ma modificare fisicamente i due vettori. Per farlo o utilizzi gli array statici fissando dei limiti per le dimensioni scelte in fase di esecuzione oppure utilizzi l'allocazione dinamica della memoria.
Infine se ti può essere utile ti consiglio il seguente corso di C++ che ritengo molto ben fatto:
http://www.bo.cnr.it/corsi-di-informatica/corsoCstandard/Lezioni/01Indice.html#virtual
Si può anche fare qualcosa come segue (in cui ho introdotto una struttura per restituire i valori ma non ha granché importanza):
struct Sequence { int start; int length; }; Sequence find_sequence(int *v, int n) { Sequence result = { 0, 0 }; if (n <= 0) { return result; } result.length = 1; int max_end = 1; for (int i = 1; i < n; ++i) { if (v[i-1] < v[i]) { ++max_end; if (max_end > result.length) { result.length = max_end; result.start = i-max_end+1; } } } return result; }
Grazie a entrambi. E' dal giorno del topic che non tocco informatica causa preparazione di altri esami, ma a breve mi ci rimetto e se avrò dubbi (come è probabile) mi faccio risentire.
Non ho capito perchè netbeans non mi segnala alcun errore quando riservo un'area di memoria variabile a un vettore. Devo cambiare qualche impostazione? Se me l'avesse segnalato da subito non sarei andato avanti con questo concetto sbagliato. Grazie.
Perché ogni compilatore implementa un certo numero di estensioni allo standard C++ che attiva di default. Quel codice è valido per il compilatore che usi. Il problema è che non lo è passando ad altri compilatori. Sinceramente non ho mai usato NetBeans e non saprei aiutarti nel settare l'opzione corretta.
Prova a settare c++11 o c++14 e nel caso anche a modificare "warning level".
Puoi anche inserire -pedantic nella riga Additional Options.
Purtroppo non è cambiato nulla, ho fatto apply ok e anche riavviato.


Click sull'immagine per visualizzare l'originale
Va bene questo pezzo di codice per l'input e l'output dei due vettori?
#include
#include
using namespace std;
void iovettore(int dim, int * vet)
{
int i;
cout<<"Scegliere la dimensione del vettore ";
cin>>dim;
vet=new int[dim];
for(i=0;i
{cout<<"Inserisci l'elemento numero "<
cin>>vet; cout<<"\n";
}
cout<<"Il vettore che hai inserito è \n";
for(i=0;i
{
cout<<" "<;
}
cout<<"\n";
}
int main()
{
int dim1=0; int * vet1[dim1];
iovettore(dim1,* vet1);
int dim2=0; int * vet2[dim2];
iovettore(dim2,* vet2);
}
Ho usato le funzioni e poi ho introdotto i vettori usando i puntatori. Dentro main, se non inizializzo dim1 e dim2 a 0 il programma da RUN FAILED.
#include
#include
using namespace std;
void iovettore(int dim, int * vet)
{
int i;
cout<<"Scegliere la dimensione del vettore ";
cin>>dim;
vet=new int[dim];
for(i=0;i
}
cout<<"Il vettore che hai inserito è \n";
for(i=0;i
cout<<" "<
}
cout<<"\n";
}
int main()
{
int dim1=0; int * vet1[dim1];
iovettore(dim1,* vet1);
int dim2=0; int * vet2[dim2];
iovettore(dim2,* vet2);
}
Ho usato le funzioni e poi ho introdotto i vettori usando i puntatori. Dentro main, se non inizializzo dim1 e dim2 a 0 il programma da RUN FAILED.
Come già detto nel post precedente ti consiglio di scrivere il codice in modo indentato, rispettare la spaziatura e inserire una sola istruzione per riga. Inoltre per postare il codice qui sul forum c'è la funzionalità "code".
Non serve includere la libreria cstdlib.
Conviene inoltre utilizzare le funzioni per svolgere un solo compito alla volta. Nel caso in esame ti consiglio di creare una funzione per l'input ed una per l'output, mentre l'allocazione dinamica della memoria la effettuerei nel main.
E' sempre buona prassi deallocare la memoria allocata in precedenza con "delete".
Il main presenta vari errori che mi fanno pensare che la parte sui puntatori e l'operatore di dereferenziazione non ti è molto chiara. Per esempio con "int * vet1[dim1]" stai dichiarando un array di dim1 puntatori a int e non un puntatore ad int. Inoltre la funzione "iovettore" si aspetta come secondo argomento un puntatore ad int mentre tu tramite l'operatore di dereferenziazione gli stai passando un int (int e *int sono tipi diversi).
Giusto per capire io avrei fatto una cosa del genere:
EDIT:
Mi correggo, poichè con "int * vet1[dim1]" stai dichiarando un array di puntatori, vet1 equivale ad un puntatore a puntatore e quindi utilizzando l'operatore di dereferenziazione con "*vet1" stai effettivamente passando a "iovettore" un puntatore ad int e cioè proprio quello che la funzione si aspetta come secondo argomento . Infatti in caso di contrasto di tipi non avrebbe proprio compilato. In ogni caso non so quanto sia voluta come cosa visto che se l'esercizio è sempre lo stesso bastano solo due puntatori ad int.
In realtà il problema non sussiste anche se inizializzi dim1 e dim2 a 3, 17 e 235. Il problema è che se non inizializzi una variabile, questa assumerà un valore casuale, e se questo valore è molto grande e non c'è abbastanza memoria disponibile, il programma in fase di esecuzione darà errore.
Non serve includere la libreria cstdlib.
Conviene inoltre utilizzare le funzioni per svolgere un solo compito alla volta. Nel caso in esame ti consiglio di creare una funzione per l'input ed una per l'output, mentre l'allocazione dinamica della memoria la effettuerei nel main.
E' sempre buona prassi deallocare la memoria allocata in precedenza con "delete".
Il main presenta vari errori che mi fanno pensare che la parte sui puntatori e l'operatore di dereferenziazione non ti è molto chiara. Per esempio con "int * vet1[dim1]" stai dichiarando un array di dim1 puntatori a int e non un puntatore ad int. Inoltre la funzione "iovettore" si aspetta come secondo argomento un puntatore ad int mentre tu tramite l'operatore di dereferenziazione gli stai passando un int (int e *int sono tipi diversi).
Giusto per capire io avrei fatto una cosa del genere:
#include <iostream> using namespace std; void input(int dim, int *v) { for(int i = 0; i < dim; i++) { cout << "v[" << i + 1 << "] = "; cin >> v[i]; } } void output(int dim, int *v) { for(int i = 0; i < dim; i++) { cout << v[i] << " "; } } int main() { int dim; cout << "DIMENSIONE VETTORE: "; cin >> dim; int *v = new int[dim]; input(dim, v); output(dim, v); delete[] v; }
EDIT:
Mi correggo, poichè con "int * vet1[dim1]" stai dichiarando un array di puntatori, vet1 equivale ad un puntatore a puntatore e quindi utilizzando l'operatore di dereferenziazione con "*vet1" stai effettivamente passando a "iovettore" un puntatore ad int e cioè proprio quello che la funzione si aspetta come secondo argomento . Infatti in caso di contrasto di tipi non avrebbe proprio compilato. In ogni caso non so quanto sia voluta come cosa visto che se l'esercizio è sempre lo stesso bastano solo due puntatori ad int.
Dentro main, se non inizializzo dim1 e dim2 a 0 il programma da RUN FAILED.
In realtà il problema non sussiste anche se inizializzi dim1 e dim2 a 3, 17 e 235. Il problema è che se non inizializzi una variabile, questa assumerà un valore casuale, e se questo valore è molto grande e non c'è abbastanza memoria disponibile, il programma in fase di esecuzione darà errore.
Grazie, ho ristudiato un pò la parte sui puntatori e mi è certamente più chiara, anche se credo ci sono ancora margini di miglioramento. Ho visto il tuo codice, poi ho provato a scriverne uno io per quanto riguarda le funzioni di input e output del vettore ed è venuto fuori questo:
Non capisco come mai la funzione ovettore non restituisce nulla.
#include<iostream> using namespace std; void ivettore(int dim,int* vett) { cout<<"Scegliere la dimensione del vettore "; cin>>dim; int i; for(i=0;i<dim;i++) { cout<<"\nInserisci l'elemento numero "<<i+1<<" del vettore "; cin>>vett[i]; } } void ovettore(int dim,int* vett) { cout<<"\nIl vettore che hai inserito è "; for(int i=0;i<dim;i++) { cout<<" "<<vett[i]; } } int dim1; int* vett1=new int[dim1]; int dim2; int* vett2=new int[dim2]; int main() { ivettore(dim1,vett1); ovettore(dim1,vett1); ivettore(dim2,vett2); ovettore(dim2,vett2); }
Non capisco come mai la funzione ovettore non restituisce nulla.
Non ha molto senso dichiarare "dim" e "vett" al di fuori del main (ossia come variabili globali).
Per quanto riguarda la tua domanda:
- le variabili globali se non inizializzate sono inizializzate di default a 0;
- quindi con l'istruzione " int* vett=new int[dim]; " stai allocando memoria per un array di 0 interi (non so il motivo per cui la funzione " ivettore " non dà problemi);
- nella funzione "ivettore" l'argomento "dim" è passato per valore e quindi qualsiasi sua modifica all'interno della funzione non avrà nessun effetto al di fuori di essa (ossia la variabile globale "dim" sarà ancora 0);
- quindi nel momento in cui viene chiamata la funzione "ovettore", essendo dim = 0, il ciclo for non viene eseguito.
Affinchè il programma faccia quello che dovrebbe fare (nonostante la presenza di numerosi errori), basta passare nella funzione "ivettore" l'argomento "dim" non per valore, ma per riferimento, ossia " void ivettore (int &dim, int *vett) ".
Inoltre l'allocazione dinamica della memoria va fatta una volta nota la quantità di memoria da allocare, ossia una volta nota "dim" (cosa che nel tuo caso non avviene).
Cmq se imposti il main come nel codice che ho postato in precedenza non dovresti avere problemi.
Per quanto riguarda la tua domanda:
- le variabili globali se non inizializzate sono inizializzate di default a 0;
- quindi con l'istruzione " int* vett=new int[dim]; " stai allocando memoria per un array di 0 interi (non so il motivo per cui la funzione " ivettore " non dà problemi);
- nella funzione "ivettore" l'argomento "dim" è passato per valore e quindi qualsiasi sua modifica all'interno della funzione non avrà nessun effetto al di fuori di essa (ossia la variabile globale "dim" sarà ancora 0);
- quindi nel momento in cui viene chiamata la funzione "ovettore", essendo dim = 0, il ciclo for non viene eseguito.
Affinchè il programma faccia quello che dovrebbe fare (nonostante la presenza di numerosi errori), basta passare nella funzione "ivettore" l'argomento "dim" non per valore, ma per riferimento, ossia " void ivettore (int &dim, int *vett) ".
Inoltre l'allocazione dinamica della memoria va fatta una volta nota la quantità di memoria da allocare, ossia una volta nota "dim" (cosa che nel tuo caso non avviene).
Cmq se imposti il main come nel codice che ho postato in precedenza non dovresti avere problemi.
In alternativa, nel caso di array la cui dimensione non è nota a priori, è probabilmente meglio usare la classe std::vector. Ma suppongo non sia stata insegnata.
Ho rifatto l'esercizio cercando di tenere conto dei vari consigli e usando le funzioni, però usando le funzioni mi sembra troppo complesso. Causa mancanza di voglia, manca la parte finale sulla memorizzazione e la visualizzazione di S1 e S2. Come giustamente mi avete detto io devo creare in memoria i vettori S1 e S2 e non mostrarli e scambiarli semplicemente a video.
Come nota positiva c'è che per rifare l'esercizio ci ho messo molto meno tempo rispetto a quello impiegato per scrivere la prima versione. Come nota negativa c'è che spendo ancora troppe energie per scrivere codici già scritti in passato, cioè ci devo ripensare e non mi vengono in mente subito. Questo all'esame sarà un problema.
P.S: corretto un errore nella funzione posmaxvettore.
Come nota positiva c'è che per rifare l'esercizio ci ho messo molto meno tempo rispetto a quello impiegato per scrivere la prima versione. Come nota negativa c'è che spendo ancora troppe energie per scrivere codici già scritti in passato, cioè ci devo ripensare e non mi vengono in mente subito. Questo all'esame sarà un problema.
#include <iostream> using namespace std; void ivettore(int dim,int* V) { for(int i=0;i<dim;i++) { cout<<"Inserisci l'elemento numero "<<i+1<<"\n"; cin>>V[i]; } } void ovettore(int dim,int* V) { for(int i=0;i<dim;i++) { cout<<" "<<V[i]; } } //creo una funzione per azzerare un vettore void azzeravettore(int dim,int* V) { for(int i=0;i<dim;i++) { V[i]=0; } } int maxvettore(int dim,int* V) { int max=V[0]; for(int i=1;i<dim;i++) { if(max<V[i]) { max=V[i]; } } return max; } int posmaxvettore(int dim,int* V) { int max=V[0]; int posmax=0; for(int i=1;i<dim;i++) { if(max<V[i]) { posmax=i; } } return posmax; } int main() { int dim1; cout<<"Scegli la dimensione di V1\n"; cin>>dim1; int* V1=new int[dim1]; ivettore(dim1,V1); int dim2; cout<<"Scegli la dimensione di V2\n"; cin>>dim2; int* V2=new int[dim2]; ivettore(dim2,V2); cout<<"V1 ="; ovettore(dim1,V1); cout<<"\nV2 ="; ovettore(dim2,V2); //introduco i vettori indpar1 e lung1 e le altre variabili necessarie int j1=0; int l1=1; int uno=1; int* indpar1=new int[dim1]; int* lung1=new int[dim1]; //inizializzo a zero i vettori indpar1 e lung1 azzeravettore(dim1-1,indpar1); azzeravettore(dim1-1,lung1); //memorizzo nelle componenti dei vettori indpar1 e lung1 rispettivamente l'indice di partenza e la lunghezza delle sequenze crescenti trovate a ogni passo in V1 for(int i=1;i<dim1;i++) { if (V1[i-1]<V1[i]) {indpar1[i-1]=j1; lung1[i-1]=++l1;} else {j1=i-1;j1++;l1=uno;} } //introduco i vettori indpar1 e lung1 e le altre variabili necessarie int j2=0; int l2=1; int UNO=1; int* indpar2=new int[dim2]; int* lung2=new int[dim2]; //inizializzo a zero i vettori indpar1 e lung1 azzeravettore(dim2-1,indpar2); azzeravettore(dim2-1,lung2); //memorizzo nelle componenti dei vettori indpar2 e lung2 rispettivamente l'indice di partenza e la lunghezza delle sequenze crescenti trovate a ogni passo in V2 for(int i=1;i<dim2;i++) { if (V2[i-1]<V2[i]) {indpar2[i-1]=j2; lung2[i-1]=++l2;} else {j2=i-1;j2++;l2=UNO;} } //richiamo le funzioni maxvettore e posmaxvettore cout<<"\nLa più lunga sequenza ordinata S1 contenuta in V1 ha lunghezza "<<maxvettore(dim1-1,lung1)<<" e parte dall'elemento "<<indpar1[posmaxvettore(dim1-1,lung1)]+1; cout<<"\nLa più lunga sequenza ordinata S2 contenuta in V2 ha lunghezza "<<maxvettore(dim2-1,lung2)<<" e parte dall'elemento "<<indpar2[posmaxvettore(dim2-1,lung2)]+1; cout<<"\nS1 = "; for(int i=indpar1[posmaxvettore(dim1-1,lung1)];i<indpar1[posmaxvettore(dim1-1,lung1)]+maxvettore(dim1-1,lung1);i++) { cout<<" "<<V1[i]<<" "; } cout<<"\nS2 = "; for(int i=indpar2[posmaxvettore(dim2-1,lung2)];i<indpar2[posmaxvettore(dim2-1,lung2)]+maxvettore(dim2-1,lung2);i++) { cout<<" "<<V2[i]<<" "; } }
P.S: corretto un errore nella funzione posmaxvettore.