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

di il
51 risposte

51 Risposte - Pagina 3

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

    AldoBaldo ha scritto:


    Nippolo: "Detto questo trovo sia la traccia che la tua interpretazione parecchio ambigue!"

    Ecco un altro caso di quel che affermavo dicendo che chi scrive esercizi a volte dovrebbe prestare più attenzione alla lingua che usa e al modo di gestirne i significati (a meno che nel testo che ci è stato proposto manchi un pezzo).

    Comunque sia, a parte la formulazione discutibile, "ricevere in input due array di interi con le relative dimensioni e determini se la somma degli elementi del più piccolo è contenuto nel più grande secondo me con "array più piccolo" e "array più grande" intende "array col minor numero di elementi" e "array col maggior numero di elementi". Il che porta a una soluzione completamente diversa da quella che state prospettando.

    Caspita, mi sa che hai ragione.
    Allora cambierebbe così:
    
    
    // Ricevere in input due array di interi con le relative dimensioni e determini
    // se la somma degli elementi del più piccolo è contenuto nel più grande.
    
    #include <iostream>
    using namespace std;
    int main ()
    bool ricerca_lineare () //nonsoscriverelafunzionebooleanadiricercalineare
    {
    	for (int i = 0; i < ?; i++)
    	if (???)
    	return true;
    	else
    	return false;
    }
    {
    	cout << "Inserisci la dimensione del primo array: ";
    	cin >> x;
    	cout << "Inserisci la dimensione del secondo array: ";
    	cin >> y;
    	int a [x]; 
    	int b [y];  
    	int min;
        int somma1 = 0, somma2 = 0;
        cout << "Inserisci interi nel primo array: " << endl; // Riempio ambedue gli array
    	for (int i = 0; i < x; i++)
    	{
    		cin >> a [i];
    		somma1 = somma1 + a [i];
    	}
    	cout << "Inserisci interi nel secondo array: " << endl;
    	for (int i = 0; i < y; i++)
    	{
    		cin >> b [i];
    		somma2 = somma2 + b [y];
    	}
    	if (x<y) // Stabilisco qual e' l'array con dimensione minore
    	{
    	cout << "L'array piu' piccolo e' quello con dimensione " << x;
    	min = somma1;
    	bool trovato = ricerca_lineare (???); //Se il risultato e' x, applico la ricerca lineare (applico e' parolone f33 )
    	if (trovato)
    	cout << somma1 << " e' contenuto!";
    	else
    	cout << somma1 << " non e' contenuto!";
        }
    	else if (x>y) // Stessa cosa se l'array minore fosse il secondo
    	{
    	cout << "L'array piu' piccolo e' quello con dimensione " << y;
    	min = somma2;
    	bool trovato = ricerca_lineare (b, y, min);
    	if (trovato)
    	cout << somma2 << " e' contenuto!";
    	else
    	cout << somma2 << " non e' contenuto!";
    	}
    
    return0;
    }
    	
    
    Io so di avere un grande grande grande problema con ricerca lineare, binaria, bubblesort, allocazione dinamica e statica di array, puntatori.
    Da come è spiegato nelle mie dispense, con un esempio e basta, non saprei adottare la ricerca lineare.
    Da quello che ho potuto capire, affacciandomi su internet, è che la ricerca lineare consiste nel verificare se un dato elemento sia contenuto o meno all'interno di un array non per forza ordinato, bubblesort serve ad ordinare un array in senso crescente e la ricerca binaria è una ricerca "migliore" della lineare, soltanto che si può applicare su un array ordinato, perché effettua il confronto dell'elemento da cercare con l'elemento medio contenuto nell'array, etc...
    Qualche santo che riuscirebbe a darmi una mano o a fornire dispense, non so?
    Sono disperato, più leggo e più non capisco.
  • Re: Un piccolo studente che ha bisogno di una grande mano...

    Luggigi, non ho idea se può tornarti utile oppure no, però tempo fa trovai un corso completo qui

    http://www.bo.cnr.it/corsi-di-informatica/corsoCstandard/Lezioni/01Indice.html

    Se non ho capito male fa capo all'università di Bologna.

    Tornando al tuo codice... sai come fare a "buttare fuori" dal main() parti del programma ricorrendo a funzioni a parte? Perché potresti snellire un bel po' la funzione principale, ad esempio predisponendo una funzione "accessoria" che si occupi di gestire l'immissione dei due array: scriveresti il codice una volta per poi richiamarne l'esecuzione due volte, una per il primo array, l'altra per il secondo.

    Per cercare l'elemento che ti interessa hai bisogno: l'indirizzo del vettore dove cercare il valore, le dimensioni del vettore e il valore da cercare. Tipo...
    bool ricerca_lineare( int *vet, unsigned int qEl, int val ) {
        if( NULL != vet ) { // hai visto mai...
            for( unsigned int i=0; i<qEl; i++ ) {
                if( vet[i] == val ) return true;
            }
        }
        
        return false;
    }
    Ah, perché hai definito la funzione DENTRO al main()? Buttala fuori!
    Nel tuo codice, comunque, si sono altre cose che dovresti controllare.
  • Re: Un piccolo studente che ha bisogno di una grande mano...

    Sicuramente mi servirà, grazie mille per il link...
    Provo a studiarci sopra, non è facile.

    Questo è un algoritmo di ricerca?
    Ho capito che dovrò imparare a memoria altrimenti non si spiega.
    
    
    bool ricerca_lineare( int *vet, unsigned int qEl, int val ) {
        if( NULL != vet ) { // hai visto mai...
            for( unsigned int i=0; i<qEl; i++ ) {
                if( vet[i] == val ) return true;
            }
        }
        
        return false;
    }
    
    
    Da ciò che ne capisco hai creato una funzione booleana chiamata ricerca lineare.
    Perché un puntatore int *vet? unsigned int mai visto...
    int val è il valore che ti interessa, ho capito.
    Quindi se la dimensione è diversa da zero, con un ciclo for si cerca il valore e in caso ritorna true, altrimenti false.

    ///

    Ho provato ma non gira:
    
    
    // Ricevere in input due array di interi con le relative dimensioni e determini
    // se la somma degli elementi del più piccolo è contenuto nel più grande.
    #include <iostream>
    using namespace std;
    bool ricerca_lineare ( int *vet, int qEl, int val)
    {
    	if( NULL != vet ) { // hai visto mai...
            for( unsigned int i=0; i<qEl; i++ ) {
                if( vet[i] == val ) return true;
            }
        }
        
        return false;
    }
    
    int main()
    
    {
    	int x, y;
    	cout << "Inserisci la dimensione del primo array: ";
    	cin >> x;
    	cout << "Inserisci la dimensione del secondo array: ";
    	cin >> y;
    	int a [x];
    	int b [y];  
    	int min;
        int somma1 = 0, somma2 = 0;
        cout << "Inserisci interi nel primo array: " << endl;
    	for (int i = 0; i < x; i++)
    	{
    		cin >> a [i];
    		somma1 = somma1 + a [i];
    	}
    	cout << "Inserisci interi nel secondo array: " << endl;
    	for (int i = 0; i < y; i++)
    	{
    		cin >> b [i];
    		somma2 = somma2 + b [y];
    	}
    	if (x<y)
    	{
    	cout << "L'array piu' piccolo e' quello con dimensione " << x;
    	min = somma1;
    	bool trovato = ricerca_lineare (a, x, min);
    	if (trovato)
    	cout << "E' contenuto!";
    	else
    	cout << "Non e' contenuto!";
        }
    	else if (x>y)
    	{
    	cout << "L'array piu' piccolo e' quello con dimensione " << y;
    	min = somma2;
    	bool trovato = ricerca_lineare (b, y, min);
    	if (trovato)
    	cout << "E' contenuto!";
    	else
    	cout << "Non e' contenuto!";
    	}
    
    return 0;
    }
    
    
    Che mi dicesse mai, è contenuto ahahahaa
  • Re: Un piccolo studente che ha bisogno di una grande mano...

    Il nome "ricerca_lineare" è quello che le hai dato tu, io mi son limitato a non cambiarlo.

    L'unsigned int è un tipo di dato molto comune. E' un intero come gli altri, solo che ammette solo valori positivi (dunque non potrà mai valere... che so... -5). Dal momento che negli int "comuni" uno dei bit viene usato per conservare il segno, negli int senza segno si ha a disposizione un bit in più, il che ne aumenta la capienza in termini di valori positivi. Per intendersi, a 32 bit un intero col segno può avere valori compresi tra -2147483648 e 2147483647, mentre un intero senza segno può avere valori compresi tra 0 e 4294967295.

    Ho usato un unsigned int perché la variabile qEl indica la quantità di elementi nell'array, e non si può avere un array che abbia... che so... -8 elementi. Tutto qui.

    Quell'if(NULL!=vet) controlla semplicemente che non sia stato passato un puntatore non valido (qualsiasi puntatore con valore NULL, cioè zero, è considerato un puntatore non valido), perché usare un puntatore NULL significa creare potenzialmente problemi gravi al programma. E' una specie di "assicurazione sulla vita".

    Il procedimento della funzione che ti ho suggerito è elementare: prende l'array puntato da vet e lo scorre elemento per elemento fino a qEl elementi. Se trova un elemento uguale a val, la funzione restituisce subito true, ignorando gli elementi successivi. Se arriva in fondo al ciclo senza aver restituito true, significa che ha scorso tutti gli elementi senza trovarne alcuno che fosse uguale a val, per cui la funzione restituisce false.
  • Re: Un piccolo studente che ha bisogno di una grande mano...

    Rileggendo mi accorgo che mi è sfuggito il tuo interrogativo "perché un puntatore?".

    Un puntatore indica un indirizzo in memoria. Dunque, ho passato alla funzione il puntatore al vettore per farle sapere dove si trova il punto iniziale del vettore stesso. Una volta a conoscenza di quella posizione, la funzione può accedere a tutti gli elementi dell'array (che sono consecutivi e adiacenti in memoria) semplicemente incrementando in modo opportuno quell'indirizzo. Se non avessi passato alla funzione anche la quantità degli elementi presenti nel vettore, quella avrebbe comunque potuto accedere alla memoria, ma non avrebbe avuto modo di sapere dove terminano i dati validi, finendo magari per leggere/scrivere in posizioni inadeguate.

    Ah, a proposito di leggere e scrivere... visto che la funzione legge e non scrive, avrei anche potuto passare const int *vet, proprio per rimarcare al chiamante che il contenuto del vettore vet non viene mai modificato.
  • Re: Un piccolo studente che ha bisogno di una grande mano...

    Credo di aver capito come funziona questa funzione booleana di ricerca lineare, grazie mille!
    Se io avessi invece:

    "Scrivere una funzione booleana che riceva in input due array di interi con le relative dimensioni e determini se la somma degli elementi del più piccolo è contenuto nel più grande."

    Io devo inserire in input gli array con le relative dimensioni, quindi non avrei come parametri const int* vet, unsigned int qEl, int val.
    O sbaglio?
  • Re: Un piccolo studente che ha bisogno di una grande mano...

    Dunque... Se deve ricevere in input due array deve avere due puntatori a intero (uno per array) e due interi che ne indichino le dimensioni (uno per array). Ad esempio, potresti avere, che so...

    bool confronta( int *vet1, unsigned int qEl1, int *vet2, unsigned int qEl2 );
  • Re: Un piccolo studente che ha bisogno di una grande mano...

    AldoBaldo ha scritto:


    Dunque... Se deve ricevere in input due array deve avere due puntatori a intero (uno per array) e due interi che ne indichino le dimensioni (uno per array). Ad esempio, potresti avere, che so...

    bool confronta( int *vet1, unsigned int qEl1, int *vet2, unsigned int qEl2 );
    Quindi se ho ben capito, succede una cosa di questo tipo...
    
    
    bool ricerca_lineare (int *vet1, unsigned int qEl1, int *vet2, unsigned int qEl2){
    int vet1 [qEl1];
    int vet2 [qEl2];
    int min, somma1 = 0, somma2 = 0;
    cout << "Riempiamo il primo vettore: "<< endl;
    for (unsigned int i = 0; i < qEl; i++) { 
    cin >> vet1 [i];
    somma1 = somma1 + vet1 [i];
     }
    cout << "Riempiamo il secondo vettore: " << endl;
    for (unsigned int i = 0; i < qEl; i++) { 
    cin >> vet2 [i];
    somma2 = somma2 + vet2[i];
     }
    if (qEl1>qEl2)
    {min = somma2;
    for (unsigned int i=0; i < qEl1; i++) {
    if (vet1 [i] ==min) return true;
    }
    return false;
    }
    if (qEl1<qEl2)
    {min = somma1;
    for (unsigned int i=0; i < qEl2; i++){
    if (vet2 [i] == min) return true;
    }
    return false;
    }
    
    
  • Re: Un piccolo studente che ha bisogno di una grande mano...

    Sei fuori strada. Stai mischiando tra loro cose che c'entrano poco una con l'altra.
    Prova a farti una specie di traccia di quel che intendi ottenere, senza preoccuparti di trovare soluzioni subito. Dai ai tuoi passaggi dei nomi significativi, che descrivano passo per passo lo scopo che hai in mente. Non buttare subito giù il codice. E' un po' come quando ti prepari a fare un tema tirando giù una traccia che tratteggi gli argomenti che intendi POI toccare nel tema stesso...

    Una volta identificato il percorso potrai occuparti dei singoli sottoproblemi (magari "isolandoli" in funzioni dedicate) e avvicinarti alla soluzione un passo alla volta. Con un approccio così "casuale" (almeno, così appare) rischi di girare in tondo senza mai avvicinarti al risultato.

    Non so se son riuscito a dar l'idea...
  • Re: Un piccolo studente che ha bisogno di una grande mano...

    Ho provato fino ad ora e nulla, puntatori array in mente non mi vogliono entrare.
    Domani mi aspetta un viaggio in bus, mi sfoglio per bene di nuovo le dispense e domani sera provo a rispondere, seguendo il tuo consiglio.
    Io ce la sto mettendo tutta, non sto perdendo tempo e facendo robe casuali perditempo.
    Scusa se vi sto facendo perder tempo ma qui secondo me ci vuole davvero un aiuto da zero, per il livello a cui sono. :/
  • Re: Un piccolo studente che ha bisogno di una grande mano...

    Buonasera, sono tornato.
    Ho ricominciato a studiare da 0 seguendo vido leggendo dispense, siti...
    Questo programma dovrebbe generare 9 numeri compresi da 1 a 9 in modo "random"...
    Mi stampa sempre lo stesso numero: perché?
    
    
    #include <iostream> 
    #include <time.h>
    #include <stdlib.h>
    using namespace std;
    int main ()
    
    {
    	int numero;
    	for (int i = 0; i < 9; i++)
    	{
    		srand (time(NULL));
    		cout << "Il tuo numero vale: ";
    		numero = rand() % 10;
    		cout << numero << endl;
    	}
    	return 0;
    }
    
    
  • Re: Un piccolo studente che ha bisogno di una grande mano...

    Sempre lo stesso numero o PIU' VOLTE lo stesso numero?

    Un generatore di numeri casuali e' un oggetto complicato: il concetto che tu hai di 'casuale' NON E' lo stesso usato in matematica. Il generatore usa il concetto matematico CHE AMMETTE piu' volte lo stesso numero.

    Per dimostrare che la cosa funziona, genera 1.000.000 di numeri compresi tra 0 e 9 e conta quante volte sono usciti: vedrai che PIU' O MENO (NON ESATTAMENTE) sono usciti 100.000 volte ogn'uno.

    Lascia perdere i videocorsi, usa BUONI LIBRI.
  • Re: Un piccolo studente che ha bisogno di una grande mano...

    @migliorabile
    Ovviamente ognuno risponde come vuole, ma secondo la mia modesta opinione se uno è solito usare un tono molto provocatorio, deve quantomeno essere sicuro di quello che sta dicendo!

    Qui non è un problema di probabilità, ma un problema di codice... basta che il processore di chi lancia quel codice riesca a svolgere il tutto in meno di 1 secondo ed ecco che per magia esce sempre lo stesso numero!
    Prova a lanciare il seguente codice:
    #include <iostream>
    #include <ctime>
    
    using namespace std;
    
    int main ()
    {
       while(true)
       {
          srand(time(NULL));
          cout << rand() % 10 << endl;
       }
    }
    Cosa si nota?
  • Re: Un piccolo studente che ha bisogno di una grande mano...

    Ha ragione Nippolo. Il valore restituito da time() cambia ogni secondo, e non so se esistono ancora (o se sono mai esistiti) computer che impiegano più di un secondo a fare quel che viene richiesto in ogni ripetizione del ciclo. Dunque, ad ogni ripetizione srand() resetta il "seme" (e tutto il cucuzzaro che ne consegue) allo stesso modo, dal che deriva che il primo numero estratto sarà sempre lo stesso, perché la sequenza data da chiamate successiva rand(), a parità di "seme" è sempre la stessa.

    Uno potrebbe provare a "buttar fuori" dal ciclo, anticipandola, la chiamata a srand() e vedere cosa succede. Poi chiedersi perché succede proprio quel che succede (magari leggendo un po' di documentazione):

    http://www.cplusplus.com/reference/cstdlib/srand
    http://www.cplusplus.com/reference/cstdlib/rand
  • Re: Un piccolo studente che ha bisogno di una grande mano...

    Nippolo ha scritto:


    @migliorabile
    Ovviamente ognuno risponde come vuole, ma secondo la mia modesta opinione se uno è solito usare un tono molto provocatorio, deve quantomeno essere sicuro di quello che sta dicendo!

    Qui non è un problema di probabilità, ma un problema di codice... basta che il processore di chi lancia quel codice riesca a svolgere il tutto in meno di 1 secondo ed ecco che per magia esce sempre lo stesso numero!
    Prova a lanciare il seguente codice:
    #include <iostream>
    #include <ctime>
    
    using namespace std;
    
    int main ()
    {
       while(true)
       {
          srand(time(NULL));
          cout << rand() % 10 << endl;
       }
    }
    Cosa si nota?
    Mi dà srand e rand non dichiarati nello scope...
Devi accedere o registrarti per scrivere nel forum
51 risposte