Esercizio banale ma non per me

di il
57 risposte

57 Risposte - Pagina 2

  • Re: Esercizio banale ma non per me

    selfmademan ha scritto:



    l'else all'interno del for di ricerca non ha alcun senso....basta cambiare la dichiarazione delle variabili in
    Giusto, grazie!

    E' giusto quest'altro pezzo per ordinare il vettore in modo crescente?
    
    int j;
        for(j=0;j<dim;j++)
            {
            posmin=j;
            min=vett[j];
            for(i=j+1;i<dim;i++)
            {
                if(min>vett[i])
                {min=vett[i]; posmin=i;}
               
            }
            vett[posmin]=vett[j];
            vett[j]=min;
        }
        cout<<"Il vettore ordinato in modo crescente è:\n";
        for(i=0;i<dim;i++)
        {cout<<" "<<vett[i]<<" ";}
            
            
    Esistono già, descritti ovunque, algoritmi di ordinamento molto performanti (bubble sort, quick sort): non perdere nel reinventare l'acqua calda, piuttosto studia un po' prima di "schiacciare i bottoni" della tastiera.
  • Re: Esercizio banale ma non per me

    Mi sono messo a studiare le funzioni! Mi spieghereste la differenza tra questi due programmi? Funzionano allo stesso modo.
           
    #include<iostream>
    using namespace std;
     int Somma(int a, int b)
    {cin>>a; cin>>b; cout<<a+b;}
    int main()
    { int a; int b;
        Somma(a,b);
    }
    
    
    #include<iostream>
    using namespace std;
            
    int Somma(int a, int b)
    {cin>>a; cin>>b; return a+b;}
    int main()
    { int a; int b;
        cout<<Somma(a,b);
    }
    
  • Re: Esercizio banale ma non per me

    Diciamo che il primo è sbagliato perché definisce una funzione che deve ritornare un int e non lo torna, il secondo è corretto.
  • Re: Esercizio banale ma non per me

    Diciamo anche che non sono esattamente conformi alle direttive di codifica Google, anche se dubito che andrai a fare l'ingegnere per quest'ultima.

    Non mi è neppure chiaro cosa dovrebbe fare la funzione Somma
  • Re: Esercizio banale ma non per me

    +m2+ ha scritto:


    Diciamo anche che non sono esattamente conformi alle direttive di codifica Google, anche se dubito che andrai a fare l'ingegnere per quest'ultima.

    Non mi è neppure chiaro cosa dovrebbe fare la funzione Somma
    probabilmente sommare due numeri non inizializzati (stack garbage)
  • Re: Esercizio banale ma non per me

    Okok grazie ragazzi! Sono un meccanico, non amo particolarmente battere i tasti dietro a uno schermo
    Ma se voglio definire n variabili di tipo int, ad esempio int indice1; int indice 2;..........; int indicen; come posso fare?
    Cioè io scelgo il valore di n e quindi mi vengono definite le n variabili.
    Stavo pensando a
    for(i=1; i<=n; i++)
    {int indicen;} ma ovviamente non funziona poichè indicen viene riconosciuto come il nome della variabile.
  • Re: Esercizio banale ma non per me

    selfmademan ha scritto:


    Okok grazie ragazzi! Sono un meccanico, non amo particolarmente battere i tasti dietro a uno schermo
    Ma se voglio definire n variabili di tipo int, ad esempio int indice1; int indice 2;..........; int indicen; come posso fare?
    Cioè io scelgo il valore di n e quindi mi vengono definite le n variabili.
    Stavo pensando a
    for(i=1; i<=n; i++)
    {int indicen;} ma ovviamente non funziona poichè indicen viene riconosciuto come il nome della variabile.
    Così come l'hai scritta non si può fare in c, ma puoi dichiarare un array di n elementi.
  • Re: Esercizio banale ma non per me

    selfmademan ha scritto:


    Okok grazie ragazzi! Sono un meccanico, non amo particolarmente battere i tasti dietro a uno schermo
    Bene, la domanda è
    cosa vorresti che facesse quella funzione?

    Chiedere due numeri da tastiera, e riportarne la somma.
    Oppure sommare due numeri che le vengono passate?
    Ma se voglio definire n variabili di tipo int, ad esempio int indice1; int indice 2;..........; int indicen; come posso fare?
    Cioè io scelgo il valore di n e quindi mi vengono definite le n variabili.
    Stavo pensando a
    for(i=1; i<=n; i++)
    {int indicen;} ma ovviamente non funziona poichè indicen viene riconosciuto come il nome della variabile.
    Direi a "occhio" che non hai una gran dimestichezza, ma è normale.
    Rammenta che il C non è altro che una sorta di "assembly semplificato", nasce una 50ina di anni fa, quindi è tutto molto più semplice e "brutale" di quanto puoi pensare.
    Nel bene, e nel male.

    Tornando alla domanda come sopra specificato esiste il concetto di array, o vettore, di "qualcosa".
    Che non è altro che un blocco di memoria lungo dimensionedell'elemento*numeroelementi (in realtà la cosa non è proprio così banale con le struct, e con packet, ma non complichiamo il discorso più del necessario).

    C lavora unicamente (a parte i tipi "banali", quali interi, float e poco più) con... celle di memoria, proprio come un programma Assembler.

    L'allocazione di queste memorie (tralascio i formalismi dei linguaggio, le mitiche funzioni di allocazione che si studiavano a MTI) può avvenire, alla stragrossa, in 3 modi

    1) implicito, sullo stack (e facciamo finta di niente, per ora)
    2) esplicito, con dichiarazione statica (cioè dici "voglio 143 variabili intere, non una di meno, non una di più, e te lo dico quando scrivo il programma
    3) esplicito, a runtime. Il programma ti chiede "quante variabili intere vuoi?" e ne crea TOT (quante richieste). Usualmente si usano funzioni di libreria tipo malloc() (e cugine varie) le quali predispongono una certa "fetta" della memoria diciamo "libera" (una volta si chiamava heap, ma poi --- cuttone ---).

    Nel tuo caso, quindi, puoi utilizzare i metodi 2 o 3.
    Il metodo (2) non prevede la "crescita": se hai 143 variabili, e ne vuoi 144, non puoi.
    Il metodo (3) neppure prevede l'aumento: hai allocato 143 variabili, e 143 rimangono. Tuttavia, essendo strutture dati allocate dal programma, sta al programma (quindi al programmatore, cioè ... te...) nel caso prevedere la possibilità di aumentare lo spazio.
    Come? Fatti tuoi.
    Devi inventarti, proprio di sana pianta (a meno che non utilizzi librerie già confezionate) come operare.
    Puoi utilizzare sistemi "brutali", tipo "se vuoi una variabile in più rispetto alle K iniziale, ne allochi altre K+1, poi ci copi sopra le K, e rilasci le prime K".
    A variazioni tra le più disparate: se vuoi una variabile in più, ne allochi T in più (cioè K+T) nell'ipotesi che se ne vuoi una, poi ne chiederai 2, e fino a T non sarà necessario ricopiarle.
    Oppure con una lista, cioè il vettore in realtà non esiste, ma avrai una struttura più complessa (con chunk di dati e un puntatore al prossimo chunk), che potrà essere di due elementi (valore-puntatore), ma con grande overhead ed inoltre frammentazione dello heap, oppure "figa"; cioè chunk-dimensione-puntatore, eventualmente a dimensione variabile (queste strutture dati sono usate più in situazioni come filesystem che algoritmi da RAM, ma nulla lo vieta).


    Insomma O utilizzi strutture predisposte dal linguaggio (in C praticamente non esistono, o meglio sono banali), O utilizzi funzioni di libreria, O te le scrivi "a manina" O utilizzi librerie "più potenti" (quelle di C++).

    Per inciso non parto sul pippone di C++ e perchè ormai è diventato una schifezza stile Java, e infatti mentre negli anni 90 sembrava IL linguaggio "fico", ora è non dico abbandonato, ma comunque molto ridimensionato e più un C "con qualcosa" che un idioma a tutto tondo [niente spiegone difetti C++, non li capiresti, ancora ]
  • Re: Esercizio banale ma non per me

    Ti ringrazio per la risposta dettagliata! Sono partito qualche mese fa con l'informatica totalmente da zero (no programmazione al liceo) quindi penso sia normale l'insicurezza che traspare Mi sono studiato anche un pò di teoria dei calcolatori, e, pur avendo imparato molto ho capito che l'argomento è veramente molto complesso e occorrono anni di studio. E' veramente interessante e affascinante però non posso allontanarmi da quelli che sono veramente i miei obiettivi e cioè la laurea in meccanica.
    L'ultima domanda mi è venuta in mente nel tentativo di impostare una soluzione all'esercizio che ho postato all'inizio ma poi ho trovato questa strada che spiego sotto:
    Va bene se definisco un vettore chiamato "lunghezza" che memorizza nella sua i-esima componente la lunghezza della i-esima serie crescente trovata nel vettore in ingresso? Sto cercando di mettere a punto il codice ma penso di essere ancora in alto mare. Quindi mi calcolo l'elemento max nel vettore "lunghezza" e ho la lunghezza della serie più lunga. Per sapere però qual è la serie crescente più lunga non mi basta conoscerne la lunghezza, ma devo sapere anche da che indice parte, e qui ci sto ancora lavorando.
    Creato il codice che dato un vettore mi restituisce la più lunga sequenza crescente, per evitare di complicare inutilmente visto che me ne serve uno uguale per l'altro vettore, mi creo la funzione. Però non ho ancora studiato i puntatori e non ho capito se mi servono nei miei esercizi

    Posto questo codice provvisorio per la creazione del vettore lunghezza ma sicuro c'è qualcosa di sbagliato, cioè funziona ma il vettore è totalmente sbagliato.
    
    
    int j=0; int lunghezza[dim]; int uno=1;
    for(i=1; i<dim; i++)
    {
        if(vett[i-1]<vett[i])
        {lunghezza[j]=uno++;}
        else
        {j++; lunghezza[j]=0;}
    }
    
  • Re: Esercizio banale ma non per me

    Ti ho già scritto sopra come puoi fare l'esercizio
  • Re: Esercizio banale ma non per me

    Ho partorito questo programma che pare funzionare. Non so se l'ho fatto come avevate in mente voi.
    
    #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];}
    }
    
    Edit: mancava la richiesta della dimensione del secondo vettore.
  • Re: Esercizio banale ma non per me

    Nessuno?
  • Re: Esercizio banale ma non per me

    Guarda, la prima cosa che noto è che è codice c++ e vedo scritto
    
    int lunghezza1[dim1];
    
    Esiste un operatore specifico per allocare dinamicamente:
    
    new
    
  • Re: Esercizio banale ma non per me

    Il mio libro dice che la dimensione del vettore deve essere una costante. non capendo come far scegliere la dimensione all'utente sono andato a intuito e ho visto che il codice funzionava e quindi ho pensato che era corretto. Che problema c'è se la dimensione è variabile? Cosa avrei dovuto fare?
  • Re: Esercizio banale ma non per me

    selfmademan ha scritto:


    Il mio libro dice che la dimensione del vettore deve essere una costante. non capendo come far scegliere la dimensione all'utente sono andato a intuito e ho visto che il codice funzionava e quindi ho pensato che era corretto. Che problema c'è se la dimensione è variabile? Cosa avrei dovuto fare?
    Quello che hai fato, sicuramente funziona, ma è sbagliato essendo codice C++.
    Quello che stai utilizzando si chiama: Variable Length Arrays, che sono proibiti in C++, ma utilizzabili in c.
    Il tuo compilatore, dovrebbe darti degli warning del tipo
    
    test.c:11:16: warning: ISO C++ forbids variable length array ‘vett1’ [-Wvla]
      int vett1[dim1];
    
    Nel caso non te li stia segnalando e tu stia utilizzando gcc, aggiungi sempre le opzioni
    
    -Wall -Wextra -pedantic 
    
    Quando compili, in modo da tenere sotto controllo tutte le cose importanti.

    I VLAs sono proibiti perché in C++ esiste inoltre un operatore specifico che ti permette di allocare dinamicamente devi vettori di dimensione calcolata runtime: l'operatore new, dovresti averlo studiato come uno dei primi argomenti di C++....
    
    int *array = new int[10];
    /..... Codice utilizzando array
    delete [] array;
    
    Ti conviene dare una bella ripassata sui libri, ma anche in rete si trovano tonnellate di informazioni.

    Esistono poi anche gli std::vector, ma è un discorso più lungo che non mi sembra il caso di affrontare visto il tuo attuale punto di conoscenza, ma anche di questo argomento puoi trovare milioni di info in rete.
Devi accedere o registrarti per scrivere nel forum
57 risposte