Un piccolo studente che ha bisogno di una grande mano...

di il
51 risposte

Un piccolo studente che ha bisogno di una grande mano...

Ciao a tutti, sono uno studente di Chimica. (sì, a Chimica si studia programmazione? Neanche io lo sapevo...)
Tra un mesetto ho l'esame di programmazione C++ e diciamo che in queste vacanze sto studiando, forse tantissimo questa materia...
Sostanzialmente ho qualche problemino con ricerca lineare, binaria e bubblesort (array), puntatori, capire quando utilizzare il passaggio per riferimento/puntatore invece che per valore per quanto riguarda le funzioni... sostanzialmente ci vuole pratica.
Ho stampato più dispense, oltre quella fornita dal corso, per imparare.
Reputo che non si possa imparare a programmare da un giorno all'altro, per cui vorrei chiedervi ogni tanto una mano se possibile qui, proponendo qualche quesito da cui non riesco a uscirne fuori.

" Scrivere un programma che legga in input una matrice di interi e un array di interi e valuti se l’array è contenuto nella matrice (cioè se è un sotto-array di almeno una riga della matrice). "
Di questo sostanzialmente non capisco la traccia

//

" Carica da tastiera un array di n elementi e lo stampa invertendo i suoi elementi. "
Sostanzialmente so creare un array e inserire elementi (for) ma stamparli invertiti, è un po' strano.. forse un for al contrario?

Es:
// Carica da tastiera un array di n elementi e lo stampa invertendo i suoi elementi.
#include <iostream>
using namespace std;

int main ()
{
int N;
cout << "Inserisci la dimensione dell'array: ";
cin >> N;
int a [N];
cout << "Gli elementi dell'array sono: " << endl;
for (int i = 0; i < N; i++)
{
cin >> a ;
}
cout << "Gli elementi rovesciati dell'array sono invece: " << endl;
for (int j = N; j >= 0; j--)
{
cout << a[j] << endl;
}
return 0;
}

Diciamo che in cout mi stampa uno zero di troppo

51 Risposte

  • Re: Un piccolo studente che ha bisogno di una grande mano...

    Con for(int j = N; j >= 0; j--), se ci pensi, il ciclo viene ripetuto N+1 volte, a partire da una posizione che è OLTRE l'ultimo elemento dell'array.

    In merito alla traccia che non ti è chiara, penso che chieda di verificare se l'array coincide almeno in parte con almeno una delle righe della matrice. Ad esempio, l'array 6 4 8 coincide in parte con la seconda e con l'ultima riga di questa matrice:

    5 1 2 5 6
    3 1 6 4 8
    4 4 5 6 2
    3 6 4 8 9
  • Re: Un piccolo studente che ha bisogno di una grande mano...

    AldoBaldo ha scritto:


    Con for(int j = N; j >= 0; j--), se ci pensi, il ciclo viene ripetuto N+1 volte, a partire da una posizione che è OLTRE l'ultimo elemento dell'array.
    Hai ragione, ora che ci penso i è minore di N, non è uguale.
    Per cui il secondo ciclo for dovrà essere un: for (int j = N - 1; j >= 0; j--)
    Grazie mille
    Per la traccia dell'altro esercizio... rimane di un linguaggio a me non comprensibile.

    EDIT:

    Esercizio: "Carica da tastiera un array di n elementi e lo stampa invertendo il primo elemento con l'ultimo, il secondo con il penultimo, ecc. "
    A vigor di logica si dovrebbe utilizzare sempre un for... però qui i parametri del for secondo me sono leggermente più complicati... non devo più fare una unica iterazione al contrario... ma è diciamo alternata.
  • Re: Un piccolo studente che ha bisogno di una grande mano...

    Ho appena aggiunto una modifica alla risposta precedente.

    Quando ti sembra di essere un impedito perché non capisci il testo di un esercizio, considera che alle volte chi scrive quegli esercizi ne sa un botto in termini di programmazione, ma ha dei vistosi limiti sotto altri aspetti. Ad esempio, nel padroneggiare l'espressività della lingua italiana -- l'ambiguità è all'ordine del giorno.
  • Re: Un piccolo studente che ha bisogno di una grande mano...

    AldoBaldo ha scritto:


    Ho appena aggiunto una modifica alla risposta precedente.
    Grazie mille per la delucidazione.
    Proverò a ragionarci un po' sopra tra questa sera e domani... gentilissimo, grazie mille ancora.
    Invece io avevo modificato la risposta precedente, aggiungendo un quesito simile a quello che ho risolto al grazie al suo aiuto!
    Senza fretta ovviamente, prima con calma un esercizio e poi si passa a quello successivo!
  • Re: Un piccolo studente che ha bisogno di una grande mano...

    L'esercizio dello scambio, alla fine, porta sempre all'inversione dell'array. Una volta ottenuti i dati dall'input, richiede un unico ciclo con una quantità di ripetizioni pari alla metà della quantità degli elementi contenuti nell'array.
  • Re: Un piccolo studente che ha bisogno di una grande mano...

    AldoBaldo ha scritto:


    L'esercizio dello scambio, alla fine, porta sempre all'inversione dell'array. Una volta ottenuti i dati dall'input, richiede un unico ciclo con una quantità di ripetizioni pari alla metà della quantità degli elementi contenuti nell'array.
    Nulla, mi sono arreso... è da ieri sera che provo.

    Su internet ho trovato questo ciclo:

    for(int x=0, y=n-1; x<n/2; x++, y--){ //questo ciclo inverte gli elementi tra loro
    box=array[y];
    array[y]=array[x];
    array[x]=box;
    }

    dove n è la dimensione dell'array.
    Non capisco proprio la logica, mai visto un ciclo for con 5 iterazioni
    Non capisco neanche perché bisogna, come hai suggerito anche tu, richiedere un ciclo con ripetizioni pari alla metà della dimensione dell'array...
    Scusami.
  • Re: Un piccolo studente che ha bisogno di una grande mano...

    CON UNA SERIE CON QUANTITA' DISPARI DI ELEMENTI

    1 2 3 4 5 6 7 la serie originale
    7 2 3 4 5 6 1 scambi il primo con l'ultimo (1 con 7)
    7 6 3 4 5 2 1 poi il secondo col penultimo (2 con 6)
    7 6 5 4 3 2 1 poi il terzo col terzultimo (3 con 5)

    Finito; come vedi hai fatto 7/2 ripetizioni (7/2 fa 3 e mezzo, ma con il "troncamento" della divisione tra interi il "mezzo" viene eliminato, quindi 3 risulta essere la meta' di 7. Nota che se prosegui oltre con le ripetizioni, torni alla serie iniziale.


    CON UNA SERIE CON QUANTITA' PARI DI ELEMENTI

    1 2 3 4 5 6 la serie originale
    6 2 3 4 5 1 scambi il primo con l'ultimo (1 con 6)
    6 5 3 4 2 1 poi il secondo col penultimo (2 con 5)
    6 5 4 3 2 1 poi il terzo col terzultimo (3 con 4)

    Finito; questa volta hai fatto 6/2 ripetizioni; trattandosi di un numero pari, non si pone neppure la questione del "troncamento". Nota che se prosegui oltre con le ripetizioni, torni alla serie iniziale.

    La questione delle "cinque iterazioni" (penso tu intenda far riferimento alle cinque operazioni che ci sono tra le parentesi del for) è in realtà molto semplice. Se rivedi la descrizione del modo in cui è strutturato un for trovi che ci sono tre elementi:

    1) qualcosa da fare prima che inizino i cicli (solo una volta)
    2) qualcosa da controllare prima di ogni ripetizione (fin dalla prima)
    3) qualcosa da fare al termine di ogni ciclo, prima del prossimo controllo

    Ciascuno dei tre elementi può contenere istruzioni multiple separate da virgole. Quelle istruzioni vengono eseguite in sequenza, dalla prima all'ultima così come si presentano.

    Ecco quindi che for(int x=0, y=n-1; x<n/2; x++, y--) significa:

    (qualcosa da fare prima che inizino i cicli (solo una volta))
    1) dichiara una variabile intera x e inizializzala a 0
    2) dichiara una variabile intera u e inizializzala a n-1

    (qualcosa da controllare prima di ogni ripetizione (fin dalla prima))
    3) controlla che x<n/2; se è così esegui il prossimo ciclo, se no esci dal for

    (qualcosa da fare al termine di ogni ciclo, prima del prossimo controllo)
    4) incrementa x di un'unità
    5) incrementa y di un'unità

    La sequenza delle operazioni, nel tuo for (ipotizzando che n sia 5, con n/2 uguale a 2) è

    - dichiara int x=0
    - dichiara int y=n-1

    - controlla che x sia minore di n/2
    - siccome x è 0, cioè meno di n/2 esegui il corpo del ciclo
    - aggiungi 1 a x
    - aggiungi 1 a y

    - controlla che x sia minore di n/2
    - siccome x è 1, cioè meno di n/2 esegui il corpo del ciclo
    - aggiungi 1 a x
    - aggiungi 1 a y

    - controlla che x sia minore di n/2
    - siccome x è 2, cioè non meno di n/2, lascia il for

    Spero di essere stato chiaro. Comunque son certo che trovi una spiegazione simile anche sul tuo libro di testo.
  • Re: Un piccolo studente che ha bisogno di una grande mano...

    AldoBaldo ha scritto:


    CON UNA SERIE CON QUANTITA' DISPARI DI ELEMENTI

    1 2 3 4 5 6 7 la serie originale
    7 2 3 4 5 6 1 scambi il primo con l'ultimo (1 con 7)
    7 6 3 4 5 2 1 poi il secondo col penultimo (2 con 6)
    7 6 5 4 3 2 1 poi il terzo col terzultimo (3 con 5)

    Finito; come vedi hai fatto 7/2 ripetizioni (7/2 fa 3 e mezzo, ma con il "troncamento" della divisione tra interi il "mezzo" viene eliminato, quindi 3 risulta essere la meta' di 7. Nota che se prosegui oltre con le ripetizioni, torni alla serie iniziale.


    CON UNA SERIE CON QUANTITA' PARI DI ELEMENTI

    1 2 3 4 5 6 la serie originale
    6 2 3 4 5 1 scambi il primo con l'ultimo (1 con 6)
    6 5 3 4 2 1 poi il secondo col penultimo (2 con 5)
    6 5 4 3 2 1 poi il terzo col terzultimo (3 con 4)

    Finito; questa volta hai fatto 6/2 ripetizioni; trattandosi di un numero pari, non si pone neppure la questione del "troncamento". Nota che se prosegui oltre con le ripetizioni, torni alla serie iniziale.

    La questione delle "cinque iterazioni" (penso tu intenda far riferimento alle cinque operazioni che ci sono tra le parentesi del for) è in realtà molto semplice. Se rivedi la descrizione del modo in cui è strutturato un for trovi che ci sono tre elementi:

    1) qualcosa da fare prima che inizino i cicli (solo una volta)
    2) qualcosa da controllare prima di ogni ripetizione (fin dalla prima)
    3) qualcosa da fare al termine di ogni ciclo, prima del prossimo controllo

    Ciascuno dei tre elementi può contenere istruzioni multiple separate da virgole. Quelle istruzioni vengono eseguite in sequenza, dalla prima all'ultima così come si presentano.

    Ecco quindi che for(int x=0, y=n-1; x<n/2; x++, y--) significa:

    (qualcosa da fare prima che inizino i cicli (solo una volta))
    1) dichiara una variabile intera x e inizializzala a 0
    2) dichiara una variabile intera u e inizializzala a n-1

    (qualcosa da controllare prima di ogni ripetizione (fin dalla prima))
    3) controlla che x<n/2; se è così esegui il prossimo ciclo, se no esci dal for

    (qualcosa da fare al termine di ogni ciclo, prima del prossimo controllo)
    4) incrementa x di un'unità
    5) incrementa y di un'unità

    La sequenza delle operazioni, nel tuo for (ipotizzando che n sia 5, con n/2 uguale a 2) è

    - dichiara int x=0
    - dichiara int y=n-1

    - controlla che x sia minore di n/2
    - siccome x è 0, cioè meno di n/2 esegui il corpo del ciclo
    - aggiungi 1 a x
    - aggiungi 1 a y

    - controlla che x sia minore di n/2
    - siccome x è 1, cioè meno di n/2 esegui il corpo del ciclo
    - aggiungi 1 a x
    - aggiungi 1 a y

    - controlla che x sia minore di n/2
    - siccome x è 2, cioè non meno di n/2, lascia il for

    Spero di essere stato chiaro. Comunque son certo che trovi una spiegazione simile anche sul tuo libro di testo.
    Una volta che viene spiegato qualcosa sembra facile, il problema è arrivarci da solo...
    Ho capito perché si fa "N/2", il mio libro non spiega questa cosa delle 5 operazioni...
    Ho provato a scrivere un codice, con due array, però mi dà errore al ciclo for


    #include <iostream>
    using namespace std;
    int main ()
    {
    int A, B;
    cout << "Inserisci la dimensione del primo array: ";
    cin >> A;
    int v [A];
    int box;

    cout << "Gli elementi dell' array sono: " << endl;
    for (int i = 0; i < A; i++)
    {
    cin >> v ;
    }
    cout << "Gli elementi rovesciati sono: " << endl;
    for (int i = 0, int x = A - 1; i < A/2; i++, x--)
    {
    box = v ;
    v = v [y];
    v [y] = box;
    cout << v [y] << endl;
    }
    return 0;
    }

    PS: y-- invece di incrementare di 1 unità y, la diminuisce no?
    Grazie mille per la disponibilità, davvero!
  • Re: Un piccolo studente che ha bisogno di una grande mano...

    Consigli:
    LASCIA PERDERE la lettura dell'array/MATRICE da tastiera.
    Questa parte del codice la introduci solo alla fine.

    EVITA COME LA LEBBRA/EBOLA/AVIARIA/PESTE/CANCRO AI TEST...OLI di cercare codice gia' pronto in Internet: gli esercizi che devi fare sono ESTREMAMENTE semplici e se ti perdi qui, selezionare e capire codice pescato a capocchia in Internet serve solo ad aumentare i dubbi/fare pasticci.

    PARTI con un array/matrice che popoli da codice, visto che lo sai gia' fare.

    Questo riduce i tempi di esecuzione del 99%

    CONCENTRATI nel risolvere i vari problemi.

    NON FISSARTI a voler risolvere il problema via codice, PRIMA PROVA con carta a quadretti e matita, LETTERALMENTE.

    Inoltre hai due mani e a disposizione DUE 'indici' che puoi usare per fare dei ragionamenti

    I quadretti sono comodi perche' ad ogni quadretto puoi assegnare un indice che parte da 0 (zero):
    - un vettore e' una serie di quadretti messi in verticale (andrebbe bene anche in orizzontale, ma e' una convenzione utile anche in altri casi)
    - una matrice e' una serie di quadretti all'interno di un rettangolo (righe, colonne)

    Se non riesci a risolvere l'esercizio, NON INTESTARDIRTI sull'esercizio completo, ma tenta di risolvere una sua versione semplificata. Invece di scambiare il primo elemento con l'ultimo, scambia il primo con il secondo, il secondo con il terzo, ... Se e' ancora troppo complicato, il primo con il primo, il secondo con il secondo, ... e questo e' decisamente semplice: NON DEVI FARE NIENTE, e non fare niente e' decisamente semplice

    @AldoBaldo, mi pare che te l'ho gia' detto: NON INCASINARE LA VITA a chi vuoi aiutare introducendo COMPLICAZIONI INUTILI.

    L'uso di istruzioni multiple NON E' NECCESSARIO ed incasina ancora di piu' chi e' alle prime armi e non riesce nemmeno a gestire un semplice indice per scandire un vettore.
  • Re: Un piccolo studente che ha bisogno di una grande mano...

    AldoBaldo ha scritto:


    Quando ti sembra di essere un impedito perché non capisci il testo di un esercizio, considera che alle volte chi scrive quegli esercizi ne sa un botto in termini di programmazione, ma ha dei vistosi limiti sotto altri aspetti. Ad esempio, nel padroneggiare l'espressività della lingua italiana -- l'ambiguità è all'ordine del giorno.
    Giusto come nota: EVITA affermazioni del genere!
    Nessuno e' esente da diffetti.
  • Re: Un piccolo studente che ha bisogno di una grande mano...

    Io so di avere problemi con array, matrici, puntatori, passaggio per &...
    (Sicuramente scriverò altre volte, puntatori - passaggio per & - matrici non le ho ancora affrontate per bene)

    Sto cercando di fare più esercizi possibili, mi dispiace che ci sia stato questo disguido tra voi due per questa mia discussione.
    Questo codice usa un'istruzione multipla a quanto ho capito però C++ non la legge, il for me lo dà come errore (sulle dispense che ho letto mai visti for di questo tipo)...

    #include <iostream>
    using namespace std;
    int main ()
    {
    int A, B;
    cout << "Inserisci la dimensione del primo array: ";
    cin >> A;
    int v [A];
    int box;

    cout << "Gli elementi dell' array sono: " << endl;
    for (int i = 0; i < A; i++)
    {
    cin >> v ;
    }
    cout << "Gli elementi rovesciati sono: " << endl;
    for (int i = 0, int x = A - 1; i < A/2; i++, x--)
    {
    box = v ;
    v = v [y];
    v [y] = box;
    cout << v [y] << endl;
    }
    return 0;
    }

    Forse l'uso di questo for "diverso" da quelli usati in precedenza è "troppo" per me, sinceramente non ci sarei mai arrivato anche se ora ho capito ed ha senso come cosa...
    Posso provare a ripetere, come suggerimento di migliorabile, l'esercizio... partendo da una versione più semplice, magari non scambiare necessariamente primo con ultimo etc... Però sinceramente non trovo altre soluzioni, mi impegnerò e in caso vi posterò qui i risultati.
  • Re: Un piccolo studente che ha bisogno di una grande mano...

    Ci sono i tag APPOSITI per avere il codice formattato in modo corretto, USALI,
    altrimenti non si capisce niente..

    @luggigi avere problemi E' NORMALE.

    Lascia decidere a NOI chi capisce cosa.

    Il C++ accetta senza problemi la sintassi 'strana' proposta da AldoBaldo. Che poi stranan non e'

    I pasticci NON SONO nel ciclo for in se, ma NEL COME LO USI!

    1) ERRORE:
    
    for (int i = 0, int x = A - 1; i < A/2; i++, x--)
    
    si scrive cosi':
    
    for (int i = 0, x = A - 1; i < A/2; i++, x--)
    
    NOTA che c'e' UN SOLO int E NON DUE.

    Come volevasi dimostrare, USARE STRANE SINTASSI non e' mai una buona cosa, se non se ne ha la PERFETTA COMPRENSIONE.
    NON ESISTE un unico modo per scrivere il codice, ne esistono tanti quanti i programmatori

    2) ERRORE:
    
        {
            box = v [i];
            v [i] = v [y];
            v [y] = box;
            cout << v [y] << endl;
        }
    
    usi la variabile y, MA DOVE HAI DEFINITO LA VARIABILE ?????
    E' ovvio che doveva essere la variabile x

    In GENERALE: EVITA SINTASSI che non conosci. USA SOLO sintassi di cui sei certo.
  • Re: Un piccolo studente che ha bisogno di una grande mano...

    migliorabile ha scritto:


    Ci sono i tag APPOSITI per avere il codice formattato in modo corretto, USALI,
    altrimenti non si capisce niente..

    @luggigi avere problemi E' NORMALE.

    Lascia decidere a NOI chi capisce cosa.

    Il C++ accetta senza problemi la sintassi 'strana' proposta da AldoBaldo. Che poi stranan non e'

    I pasticci NON SONO nel ciclo for in se, ma NEL COME LO USI!

    1) ERRORE:
    
    for (int i = 0, int x = A - 1; i < A/2; i++, x--)
    
    si scrive cosi':
    
    for (int i = 0, x = A - 1; i < A/2; i++, x--)
    
    NOTA che c'e' UN SOLO int E NON DUE.

    Come volevasi dimostrare, USARE STRANE SINTASSI non e' mai una buona cosa, se non se ne ha la PERFETTA COMPRENSIONE.
    NON ESISTE un unico modo per scrivere il codice, ne esistono tanti quanti i programmatori

    2) ERRORE:
    
        {
            box = v [i];
            v [i] = v [y];
            v [y] = box;
            cout << v [y] << endl;
        }
    
    usi la variabile y, MA DOVE HAI DEFINITO LA VARIABILE ?????
    E' ovvio che doveva essere la variabile x

    Quindi il tipo della variabile si inserisce solo la prima volta, ho capito grazie!
    Non ho definito la variabile
    Scusami ahahaha

    Seguendo il tuo consiglio, provo a scriverlo io da zero.
    Ho immaginato un array di dimensione 7 (sul fantastico foglio a quadretti: 1 2 3 4 5 6)
    Sostanzialmente ho svolto queste operazioni macchinose ogni volta, per provare ad invertire primo - ultimo, secondo - penultimo, terzo - terzultimo e poi basta! (capito il perché ahahah)
    
    
    // Carica da tastiera un array di n elementi e lo stampa invertendo il primo elemento con l'ultimo, il secondo con il penultimo, ecc.
    #include <iostream>
    using namespace std;
    
    int main ()
    {
    	int N = 7;
    	int a [N];
    	int box;
    	cout << "Gli elementi dell'array sono: " << endl;
    	for (int i = 0; i < N; i++)
    	{
    		cin >> a [i];
    	}
    	
    	cout << "La nuova serie e': " << endl;
    	box = a [0];
    	a [0] = a [6];
    	a [6] = box;
    	cout << a [0] << endl;
    	box = a [1];
    	a [1] = a [5];
    	a [5] = box;
    	cout << a [1] << endl;
    	box = a [2];
    	a [2] = a [4];
    	a [4] = box;
    	cout << a [2] << endl;
    	cout << a [3] << endl;
    	cout << a [4] << endl;
    	cout << a [5] << endl;
    	cout << a [6];
    	
    	return 0;
    	
    }
    
    
    La fantastica parte:
    
    
    cout << a [2] << endl;
    	cout << a [3] << endl;
    	cout << a [4] << endl;
    	cout << a [5] << endl;
    	cout << a [6];
    	
    	
    diventa semplicemente:
    
    
    for (int i = 2; i < 7; i++)
    {
    cout << a [i] << endl;
    }
    
    
    Il problema è la parte che precede
    Mi metto a lavoro!
  • Re: Un piccolo studente che ha bisogno di una grande mano...

    Ricorda che gli indici degli array INIZIANO DA ZERO ed arrivano a N-1 per un array di N elementi.

    NON SERVE quotare il testo del post precedente ogni volta!
    C'e' gia!
Devi accedere o registrarti per scrivere nel forum
51 risposte