Esercizio banale ma non per me

di il
57 risposte

57 Risposte - Pagina 4

  • Re: Esercizio banale ma non per me

    +m2+ ha scritto:


    Per cominciare esci dal ciclo non appena trovi una colonna non crescente.
    Ok, uso l'istruzione break quindi.

    +m2+ ha scritto:


    poi scrivi una funzione, ovviamente, cui passi la matrice e l'indice della colonna, e che ti ritorna se è ordinata
    Ok, penso di aver capito.

    +m2+ ha scritto:


    farai un ciclo per ogni colonna, mantenendo due indici "ausiliari" per le colonne crescenti, e via
    (ovviamente se ne trovi 2 esci di nuovo dal ciclo)
    Non ho capito il discorso sugli indici.

    Scusa se sono un pò un mulo ma sono stanco
  • Re: Esercizio banale ma non per me

    Ho creato la funzione e usato il break.
    
    #include <iostream>
    
    using namespace std;
    
    void imatrice(int nrig, int ncol, int** matrice)
    {
        for(int i=0;i<nrig;i++)
        {
            for(int j=0;j<ncol;j++)
            {
                cout<<"\nInserisci l'elemento posizionato sulla riga "<<i+1<<" e sulla colonna "<<j+1<<" ";
                cin>>matrice[i][j];
            }
        }
    }
    void omatrice(int nrig, int ncol, int** matrice)
    {
        for(int i=0;i<nrig;i++)
        {
            cout<<"\n";
            for(int j=0;j<ncol;j++)
            {
                cout<<"  "<<matrice[i][j]<<"  ";
            }
        }
    }
    void colcresc(int nrig, int ncol, int** matrice, bool varbool,int col)
    {
        for(int i=1;i<nrig;i++)
            {
                if(matrice[i-1][col]<matrice[i][col])
                {
                    ;
                }
                else 
                {
                    varbool=false;
                    break;
                }
            }
            if(varbool)
            {
                cout<<"\nLa colonna "<<col+1<<" è ordinata in modo crescente.";
               
               
            }
            else
            {
                cout<<"\nLa colonna "<<col+1<<" non è ordinata in modo crescente.";
                //riporto varbool a true, cioè la resetto al valore di partenza
                varbool=true;
            }
    }
    int main()
    {
        int i;
        int j;
        int nrig;
        int ncol;
        int k;
        cout<<"Inserisci il numero di righe della matrice ";
        cin>>nrig;
        cout<<"\nInserisci il numero di colonne della matrice ";
        cin>>ncol;
        int** matrice=new int* [nrig];
        for(i=0;i<nrig;i++)
        {
            matrice[i]=new int[ncol];
        }
        imatrice(nrig, ncol, matrice);
        cout<<"\nLa matrice che hai inserito è\n";
        omatrice(nrig, ncol, matrice);
       
        bool varbool=true;
        int col;
        for(col=0;col<ncol;col++)
        {
        colcresc(nrig,ncol,matrice,varbool,col);
        }
    }
    
  • Re: Esercizio banale ma non per me

    Innanzitutto ...
    1) perchè colcresc e non testasecolonnaordinata ?
    1bis) ti consiglio di nominare le variabili in ingresso con i_qualcosa; quelle in uscita con o_qualcosa; le variabili locali senza niente, e magari le globali (se ti capitano) g_qualcosa.
    2) perchè la funzione non ritorna direttamente sì/no (che ci fai con varbool?)
    3) perchè un test "a vuoto"? Negalo
    4) in ogni caso perchè non c'è un valore predefinito per varbool (o il risultato)?
    5) mancano del tutto i controlli (ma lo vedremo poi)
    6) le variabili sono signed (cioè possono essere negative)
    7) main ritorna o non ritorna qualcosa?
    per ordine
    
    varbool=true; //// in realtà come detto sarà la funzione a ritornare, inutile fare come hai fatto (anzi deleterio)  
    for(int i=1;i<nrig;i++)
            {
                if(matrice[i-1][col]>=matrice[i][col])
                {
                    varbool=false;
                    break;
                }
            }
    
    se vuoi evitare un sistema "barbaro" (come l'exit) dovresti fare un
    
    i=1;
    varbool=true;
    while (varbool) AND (i<nrig) ... fai tante belle cose
    
  • Re: Esercizio banale ma non per me

    Ho fatto varie modifiche.
    
    #include <iostream>
    
    using namespace std;
        
    int nrig; 
    int ncol;
    int i;
    int j;
    
    void i_matrice(int** matrice)
    {
        for(int i=0;i<nrig;i++)
        {
            for(int j=0;j<ncol;j++)
            {
                cout<<"\nInserisci l'elemento posizionato sulla riga "<<i+1<<" e sulla colonna "<<j+1<<" ";
                cin>>matrice[i][j];
            }
        }
    }
    void o_matrice(int** matrice)
    {
        for(int i=0;i<nrig;i++)
        {
            cout<<"\n";
            for(int j=0;j<ncol;j++)
            {
                cout<<"  "<<matrice[i][j]<<"  ";
            }
        }
    }
    bool colonnacrescente(int** matrice, int col)
    {
        bool varbool;
        for(int i=1;i<nrig;i++)
            {  
            varbool=true;
            if(matrice[i-1][col]>=matrice[i][col])
                {
                    varbool=false;
                    return varbool;
                }
            return varbool;
            }
    }
    
    int main()
    {
        cout<<"Inserisci il numero di righe della matrice ";
        cin>>nrig;
        cout<<"\nInserisci il numero di colonne della matrice ";
        cin>>ncol;
        //allocazione matrice
        int** matrice=new int* [nrig];
        for(i=0;i<nrig;i++)
        {
            matrice[i]=new int[ncol];
        }
        i_matrice(matrice);
        cout<<"\nLa matrice che hai inserito è\n";
        o_matrice(matrice);
        int col;
        for(col=0;col<ncol;col++)
        {
            if(colonnacrescente(matrice,col))
                cout<<"\nLa colonna "<<col+1<<" è crescente.";
            else
                cout<<"\nLa colonna "<<col+1<<" non è crescente.";
        }
    }
    
  • Re: Esercizio banale ma non per me

    Aspetta aspetta.........ho avuto un'illuminazione
  • Re: Esercizio banale ma non per me

    Allora...
    bool colonnacrescente(int** i_matrice, int i_col)
    poi puoi tenere varbool o farla "saltar via".
    se la tieni varbool=true la metti fuori dal ciclo for.
    versione didattica (abbastanza diversa da quella che faresti "davvero", ma è per imparare un minimo di approccio)
    
    bool colonnacrescente(int** i_matrice, unsigned int i_quanterighe, unsigned int i_quantecolonne, unsigned int i_colonnadatestare)
    {
        bool varbool=true;
        if (!i_matrice)
        {
        /// fai qualcosa passato un puntatore nullo
        }
        else
     if (!i_quanterighe)
     {
     /// fai qualcosa ci sono zero righe nella matrice
     }
     else
     if (!i_quantecolonne)
     {
     /// fai qualcosa la matrice ha zero colonne
     }
     else
    if (i_colonnadatestare>i_quantecolonne)
     {
     // fai qualcosa vuoi testare una colonna fuori dal limite della matrice
     }
     else
     {
        for(int i=1;i<i_quanterighe;i++)
            { 
               if(i_matrice[i-1][i_colonnadatestare]>=i_matrice[i][i_colonnadatestare])
                {
                    varbool=false;
                    break;
                }
            }
      }
     return varbool;
    }
    
    in un caso del genere potresti far tornare alla funzione tre valori
    -1 => errore
    0 => la colonna NON è ordinata
    1 => la colonna è ordinata

    nel "mondo normale" è pressochè indispensabile sia verificare che non ci siano errori, sia dare un qualche genere di feedback "esterno" nel caso di errore. Ovviamente siamo nel mondo C (e non C++), quindi non avvio lo spiegone C++
  • Re: Esercizio banale ma non per me

    Poi, per inciso, lascia perdere le variabili globali (nrig, ncol) e in generale eliminale del tutto (le variabili globali), "tenendole" solo se strettamente necessario.
    ovviamente, sempre nel mondo C++, faresti qualcosa di diverso (cioè creeresti un "qualcosa" come matrice, che dispone dei relativi metodi e proprietà etc.etc.)

    se volessi "mimare" il metodo di ragionamento OOP (alla grossissima), cioè facendo una sorta di C+ allora definiresti una struttura matrice, dove metteresti dentro il numero di righe e colonne.
    E definiresti le varie funzioncelle in modo che prendano come parametro una matrice
  • Re: Esercizio banale ma non per me

    Nel "mondo reale" più probabilmente faresti qualcosa del tipo
    
    int colonnacrescente(int** i_matrice, unsigned int i_quanterighe, unsigned int i_quantecolonne, unsigned int i_colonnadatestare)
    {
        if (!i_matrice)
        {
         return -1;
    /// fai qualcosa passato un puntatore nullo
        }
        else
     if (!i_quanterighe)
     {
     return -2;
     /// fai qualcosa ci sono zero righe nella matrice
     }
     else
     if (!i_quantecolonne)
     {
     return -3;
     /// fai qualcosa la matrice ha zero colonne
     }
     else
    if (i_colonnadatestare>i_quantecolonne)
     {
     return -4;
     // fai qualcosa vuoi testare una colonna fuori dal limite della matrice
     }
     else
     {
        for(int i=1;i<i_quanterighe;i++)
            {
               if(i_matrice[i-1][i_colonnadatestare]>=i_matrice[i][i_colonnadatestare])
                {
                   return 0;
                }
            }
       return 1;
      }
    }
  • Re: Esercizio banale ma non per me

    Allora, ho tolto di mezzo varbool e usato 0 e 1 come hai suggerito. Per quanto riguarda i controlli preferirei farlo dopo visto che lo ritengo un problema secondario (meglio insistere sulle cose basilari). Al netto dei controlli, ho creato la funzione come nel tuo ultimo codice. A questo punto come procedo per tenere conto degli indici delle colonne crescenti e avere il vettore fusione?
  • Re: Esercizio banale ma non per me

    "Siano dati in ingresso una matrice di numeri interi M e un valore intero K. Scrivere un programma che verifichi se esistono almeno due colonne di M i cui valori siano ordinati in modo crescente. "

    Quindi dovrai avere qualcosa tipo (E VAI DI LOOP UNROLLING dei poveri )
    
    indicecolonna1=-1
    indicecolonna2=-1
    
    
    cicla i fino a K
        se colonnacrescente(matrice,i)
            indicecolonna1=i
            break
    
    if indicecolonna1>-1
        cicla i fino a K
           se  i<>indicecolonna1
               se colonnacrescente(matrice,i)
                  indicecolonna2=i
                  break
    if indicecolonna2>-1
        ... devi continuare
    
    
    fai attenzione: sto usando un trucchettino brutale.
    un approccio "scemo" sarebbe individuare TUTTE le colonne crescenti (e quindi ti servirebbe un vettore risultato, dove per ogni indice i memorizzi ad esempio un 1 se la relativa colonna è crescente).
    però il testo dice espressamente che ne bastano DUE, quindi superbrutalmente faccio una cosa sporcaccionissima (una specie di copia-incolla), dove mi fermo appena ne trovo DUE.

    chiaramente questo è un esempio di approccio di livello non superprincipiante (diciamo principiante e basta).

    chiaro? a quel punto si passa alla parte successiva del problema (il vettore V e la fusione)
  • Re: Esercizio banale ma non per me

    Io sono un bravo ragazzo e anziché barare come hai fatto tu prendendo solo 2 colonne io le ho prese tutte
    Dai un'occhiata a questo codice. E' solo provvisorio, mi interessa sapere solo se ci sono errori gravi. So che posso migliorarlo e snellirlo usando e definendo altre funzioni.
    E' molto cervellotico....quasi non ci capisco più nulla ora che lo rileggo, eppure l'ho scritto io. Inoltre probabilmente non interpreto correttamente la richiesta del professore di lasciare solo gli elementi che distano più di K tra loro.
    Prova a testarlo con una matrice con qualche colonna crescente.
    
    #include <iostream>
    #include<cmath>
    using namespace std;
       
    int nrig;
    int ncol;
    int i;
    int j;
    
    //questa funzione elimina nel vettore k elementi consecutivi a partire dalla posizione pos
    void elimina_elem(int k, int pos, int dim, int* v)
    {
       for(int i=0;i<=(dim+k-pos-1);i++)
        {
            v[pos-1+i]=v[pos-1+k+i];
        }
    }
    
    void imatrice(int** matrice)
    {
        for(int i=0;i<nrig;i++)
        {
            for(int j=0;j<ncol;j++)
            {
                cout<<"\nInserisci l'elemento posizionato sulla riga "<<i+1<<" e sulla colonna "<<j+1<<" ";
                cin>>matrice[i][j];
            }
        }
    }
    
    void omatrice(int** matrice)
    {
        for(int i=0;i<nrig;i++)
        {
            cout<<"\n";
            for(int j=0;j<ncol;j++)
            {
                cout<<"  "<<matrice[i][j]<<"  ";
            }
        }
    }
    
    int testasecolonnacrescente(int** matrice, int col)
    {
      for(int i=1;i<nrig;i++)
            { 
            if(matrice[i-1][col]>=matrice[i][col])
                {
                 return 0;
                }
            }
        return 1;
    }
    
    int main()
    {
        cout<<"Inserisci il numero di righe della matrice ";
        cin>>nrig;
        cout<<"\nInserisci il numero di colonne della matrice ";
        cin>>ncol;
        //allocazione matrice
        int** matrice=new int* [nrig];
        for(i=0;i<nrig;i++)
        {
            matrice[i]=new int[ncol];
        }
        imatrice(matrice);
        cout<<"\nLa matrice che hai inserito è\n";
        omatrice(matrice);
        //introduco un vettore di dimensione dim=nrig*ncol in cui memorizzare le colonne crescenti
        int dim=nrig*ncol;
        int* V=new int[dim];
        int col;
        int progressione=-1;
        for(col=0;col<ncol;col++)
        {
            if(testasecolonnacrescente(matrice,col))
            {
                cout<<"\nLa colonna "<<col+1<<" è crescente.";
                 //fase di memorizzazione delle colonne crescenti in V
                 for(i=0;i<nrig;i++)
                 {
                    ++progressione;
                    V[progressione]=matrice[i][col];
                 }
            }
            else
                cout<<"\nLa colonna "<<col+1<<" non è crescente.";
        }
        //ridimensiono V
        dim=progressione+1;
        
        //"filtro" V tenendo solo gli elementi che distano più di k.
        unsigned int k;
        cout<<"\nScegli un numero intero positivo ";
        cin>>k;
        cout<<"\nIl vettore completo delle colonne crescenti è\n";
        for(i=0;i<dim;i++)
        {
            cout<<"  "<<V[i]<<"  ";
        }
        cout<<"\nIl vettore che contiene solo gli elementi delle colonne crescenti distanti tra loro più di "<<k<<" è\n";
        for(i=1;i<dim;i++)
        {
          while(abs(V[i-1]-V[i])<=k)
          {
            elimina_elem(1,i,dim,V);
            dim=dim-1;
          }
        }
        for(i=0;i<dim;i++)
        {
            cout<<"  "<<V[i]<<"  ";
        }
    }
    
  • Re: Esercizio banale ma non per me

    E' passato un pò di tempo. Sto rifacendo gli esercizi, in particolare questo:
    Siano dati in ingresso una matrice di numeri interi M e un valore intero K. Scrivere un programma che verifichi se esistono almeno due colonne di M i cui valori siano ordinati in modo crescente. Se tale condizione risulta verificata si provveda a fondere gli elementi di tali colonne in un vettore ordinato V: nel fare questa operazione si deve garantire che il vettore V contenga solo gli elementi che sono a distanza maggiore di K tra loro. Stampare infine la matrice M, indicare gli indici delle colonne a valori crescenti eventualmente trovate e, nel caso, il vettore V ottenuto.


    Non capisco bene come interpretare la condizione "si deve garantire che il vettore V contenga solo gli elementi che sono a distanza maggiore di K tra loro. ". La richiesta secondo me è imprecisa. Sono in attesa di consigli grazie.
    
    #include <iostream>
    #include<math.h>
    #include<stdlib.h>
    
    
    using namespace std;
    void imatrice(int nrig,int ncol,int M[][100])
    {
        for(int i=0;i<nrig;i++)
        {
            cout<<"\n";
            for(int j=0;j<ncol;j++)
            {
                cout<<"Inserisci l'elemento posto alla riga "<<i+1<<" e colonna "<<j+1<<"\n";
                cin>>M[i][j];
            }
        }
    }
    void omatrice(int nrig,int ncol,int M[][100])
    {
        for(int i=0;i<nrig;i++)
        {
            cout<<"\n";
            for(int j=0;j<ncol;j++)
            {
                cout<<"    "<<M[i][j]<<"    ";
            }
        }
    }
    void ivettore(int dim,int V[])
    {
        for(int i=0;i<dim;i++)
        {
            cout<<"Inserisci l'elemento "<<i+1<<" ";
            cin>>V[i];
        }
    }
    void ovettore(int dim,int V[])
    {
        for(int i=0;i<dim;i++)
        {
            cout<<"  "<<V[i];
        }
    }
    
    
    bool colonna_crescente(int nrig,int ncol,int M[][100],int col)
    {
        for(int i=0;i<nrig-1;i++)
        {
            if(M[i][col]<M[i+1][col])
            {
                if(i+1==nrig-1)
                    return true;
            }
            else
                return false;
        }
    }
    void filtra_vettore(int dim,int V[],int dis)
    {
        for(int i=0;i<dim-1;i++)
        {
            while(abs(V[i]-V[i+1])<=dis)
            {
                if(i==dim-2)
                {
                    dim=dim-2;
                    cout<<"Il vettore che contiene solo gli elementi distanti più di "<<dis<<" è\n";
                    ovettore(dim,V);
                    exit(0);
                }
                for(int j=0;j<dim-2;j++)
                {
                    V[i+j]=V[i+j+2];
                }
                dim=dim-2;
                if(dim<=1)
                {
                  cout<<"Il vettore che contiene solo gli elementi distanti più di "<<dis<<" è\n";
                  ovettore(dim,V);
                  exit(0);
                }
            }
        }
    }
    
    int main()
    {
        int M[100][100];
        cout<<"\nNumero righe matrice ";
        int nrig;
        cin>>nrig;
        cout<<"\nNumero colonne ";
        int ncol;
        cin>>ncol;
        imatrice(nrig,ncol,M);
        cout<<"\nHai inserito la matrice ";
        omatrice(nrig,ncol,M);
        int col;
        
        int col_cresc[ncol];
        int i=-1;
        for(int col=0;col<ncol;col++)
        {
        if(colonna_crescente(nrig,ncol,M,col))
        {
            cout<<"\nLa colonna "<<col+1<<" è crescente.";
          
            ++i;
            col_cresc[i]=col;
        }
        else
        {
            cout<<"\nLa colonna "<<col+1<<" non è crescente.";
        }
        }
        
        if(i+1>=2) //i+1 rappresenta il numero di colonne crescenti
            cout<<"\nEsistono almeno 2 colonne crescenti.";
        else
            cout<<"\nNon esistono almeno 2 colonne crescenti.";
        
         int fusione_colcresc[100];
        int dim=nrig*(i+1); 
         int l=-1;
        for(int j=0;j<=i;j++)
        {
            for(int k=0;k<nrig;k++)
            {
              l++;  
            fusione_colcresc[l]=M[k][col_cresc[j]];
            }
        }
        cout<<"\nIl vettore ottenuto dalla fusione delle colonne crescenti è\n";
        ovettore(dim,fusione_colcresc);
        int dis;
        cout<<"\nLa distanza tra gli elementi deve essere maggiore di.......\n";
        cout<<"Scegli un valore ";
        cin>>dis;
        cout<<"Il vettore che contiene solo gli elementi distanti più di "<<dis<<" è\n";
        filtra_vettore(dim,fusione_colcresc,dis);
        ovettore(dim,fusione_colcresc);
    }
    
  • Re: Esercizio banale ma non per me

    Crea un altro thread con un titolo opportuno... Non si possono leggere 4 pagine per risponderti...
Devi accedere o registrarti per scrivere nel forum
57 risposte