Ricerca occorrenze in matrice

di il
44 risposte

Ricerca occorrenze in matrice

Secondo voi perchè questa procedura mi sballa "legermente" il numero di occorrenze di un elemento in matrice?
considerate che ho usato una struct con i campi val e occ per gestire le occorrenze
void calcolaOccorrenze(matrice m,int r,int c, vettore & v,int rpm){
     
     int i=0;
     while(i<r){               
                    int occ=0;
                    for( int j=0;j<c-1;j++){
                    
                    for(int k=j+1;k<c;k++)
                    if(m[i][j]==m[i][k]){
                                         occ++;
                                         cout<<m[i][j];
                                         v[i].val=m[i][j];
                                         
                                         }
                    }
                        v[i].occ=occ;
                i++;
                }
                for (int p=0;p<c;p++)
                cout<<"il numero "<<v[p].val<<" si ripete "<<v[p].occ<<" volte \n";
}

44 Risposte

  • Re: Ricerca occorrenze in matrice

    Ciao ^^,
    Allora non ho capito precisamente la traccia dell' esercizio però ti posso spiegare cosa fa questo programma che hai incollato:

    Data una riga i-esima della matrica inserisci nell' indirizzo i-esimo del vettore v l ' ultimo valore che abbia un' occorrenza e come occorenze il numero di volte che sono avvenute ( non di quel valore ma di tutti i possibili valori) . Esempio:

    una riga della matrice è formata dai seguenti numeri : 1 2 1 2
    Ci sono due occorenze ( 1 e 1 , 2 e 2 ) ma nel vettore inserirai solo l' ultimo valore che abbia un' occorrenza ( 2 ) quindi la stampa alla fine sarà:
    il valore 2 si ripete 2 volte ( penso sia questo l' errore che dici )

    Distinti Saluti,
    Alessandro
  • Re: Ricerca occorrenze in matrice

    La traccia dice : data una matrice , calcolare il numero di occorrenze degli elementi su ogni riga

    in esecuzione ho il seguente risultato :
    
    la matrice è:
    3 5 5 5 6
    2 6 7 7 7 
    2 1 1 5 6 
    6 9 2 3 3
    3 3 3 3 4
    Gli elementi che si ripetono sono:
    55577713333333//<-------troppi 3 
    
    il numero 5  si ripete 3  volte
    il numero 7  si ripete  3 volte
    il numero 1  si ripete  1 volte
    il numero 3  si ripete  1  volte
    il numero 3  si ripete   6 volte
    
  • Re: Ricerca occorrenze in matrice

    Eh si ho riletto secondo l' esempio della tua matrice ( ma non l' ho testato eseguendolo perchè mi scoccio di scrivere il programma xD ) comunque ti spiego quello che ho capito:

    Innanzitutto sono sbagliati anche gli altri perchè nella prima riga ( 5 5 5 ) ci sono due occorrenze e non tre.
    Il problema consiste nel fatto che fa lo stesso algoritmo partendo dall' elemento successivo , esempio con la prima riga:
    partiamo dalla seconda posizione ( j=1 ---> 5 ) m[0][1] == m[0][2]? si -> occ++ ( 1 )
    m[0][1] == m[0][3]) ? si - > occ++ ( 2 ) ; ora finisce il secondo ciclo e si incrementa il primo e quindi j = 2:
    m[0][2] == m[0][3] ? si ->> occ++ ( 3: ERRORE )

    Se fai lo stesso esempio con l' ultima riga vedi che ti spieghi il motivo per cui escono 6 occorrenze e non 3 . Quindi per cui penso che si possa risolvere in questo modo:
    
    void calcolaOccorrenze(matrice m,int r,int c, vettore & v,int rpm){
         
         int i=0;
         bool continuo= true;
         while(i<r)
         {               
               int occ=0;
               continuo=true;
               for( int j=0;j<c-1;j++)
               {
            	 if ( continuo )
                   for(int k=j+1;k<c;k++)
                      if(m[i][j]==m[i][k])
                      {
                          occ++;
                          cout<<m[i][j];
                          v[i].val=m[i][j];
                          continuo=false;
                      }
               }
               v[i].occ=occ;
               i++;
          }
          for (int p=0;p<c;p++)
                cout<<"il numero "<<v[p].val<<" si ripete "<<v[p].occ<<" volte \n";
    }
    
    Il problema ora ( e non risolto ) è quello che ti ho detto io prima: se ci fossero due occorrenze di valori diversi? ( esempio: 1 2 1 2 ) questo algoritmo non lo permetterà e ti darà errore semmai inserissi una matrice di questo tipo ^^.

    comunque sia controlla se funziona adesso

    DIstinti Saluti,
    Alessandro
  • Re: Ricerca occorrenze in matrice

    XD avevo appena risolto, rivedendo MOLTO attentamente mi son accorto anchio di quest'errore, in ogni caso posto il codice funzionante
    void calcolaOccorrenze(matrice m,int r,int c, vettore & v,int rpm){
         
        int  i=0;
         while (i<r){
               bool trovato=false;
               int occ=1;
               for (int j=0;j<c-1;j++){
                   if(!trovato)
               for(int k=j+1;k<c;k++)
               if(m[i][j]==m[i][k]){                  
               occ++;
               trovato=true;}
               }
               
               cout<<"\n L'elemento sulla "<<i<<" riga si ripete "<<occ<<" volte ";
               i++;
               }
                    }
  • Re: Ricerca occorrenze in matrice

    Ma se dovessi calcolare le occorrenze in tutta la matrice cosa mi suggerite?
    io avevo pensato ad una funzione booleana che verifica se un elemento è già presente, se si mi conta
    quante volte c'è.
    E' una soluzione conveniente?
  • Re: Ricerca occorrenze in matrice

    Avrai bisogno di un vettore ( di struct sempre formato da valore e num_occ ) nel quale però non conosci il riempimento a priori ( prima invece lo conoscevi perchè coincideva con il numero di righe della matrice ) e quindi lo dovrai incrementare man mano che trovi un valore che ha suoi simili nella matrice. Per ogni i-esimo elemnto fai due cicli for che vanno a leggere tutti gli altri valori della matrice e metti la condizione per verificare l' occorrenza , però per far sì che non ricapiti il problema che avevi prima , per ogni i-esimo valore dovrai verificare che esso non si trovi nel vettore delle occorenze. Si può fare
  • Re: Ricerca occorrenze in matrice

    Non ne riesco proprio a venire fuori, mi sto incasinando con il codice, ho scritto questa schifezza, credo che sia tutto sbagliato !
    
    void calcolaOccorrenzeInMatrice(matrice m,int r,int c, vettore & v,int rpm,int i,int j,int rip){
       
         int occ=0;
         for (int i=0;i<r;i++){
             for (int j=0;j<c-1;j++)
                 if(ePresente(m,r,c,i,j)){
                 conta(m,r,c,i,j,rip);             
                  v[i].val=m[i][j];
                  v[i].occ=rip;
                  }
         }
         for (int i=0;i<r;i++)
         cout<<" \n L'elemento "<<v[i].val<<" si ripete "<<v[i].occ<<" volte ";
    }
    
    bool ePresente(matrice m,int r,int c,int i,int j){
         
         for(int k=i;k<r;k++){
                 for(int q=j+1;j<c;j++)
                         if(m[i][j]==m[k][q]);
                          return true;
                         return false;
                 }
         
    }
    
    
    void conta(matrice m,int r,int c,int i, int j,int & rip){
        rip=0;
         for(int p=i;i<r;i++)
         for (int q=j;j<r;j++)
         if(m[i][j]==m[p][q])
         rip++;
         }
    
    
    
  • Re: Ricerca occorrenze in matrice

    E' più complesso, comunque incomincio a dirti che ci sono molti parametri che passi nella funzione calcolaOccorrenzeInMatrice che puoi anche non passare : int i , int j , int rip e poi int rpm dove viene utilizzato?

    Oltre questo allora il discorso è che oltre alla condizione ePresente deve anche verificare che quel valore non deve essere prensente nel vettore v ( perchè per quel valore hai già calcolato le occorrenze ). Poi il conta non devi farlo partire dalla posizione [j] ma devi sempre farlo partire da [0][0] soltanto che nel ciclo devi imporre un if del tipo:
    
    void conta(matrice m,int r,int c,int i, int j,int & rip){
        rip=0;
         for(int p=0;i<r;i++)
            for (int q=0;j<c;j++)
            {
               if ( p== i && q == j )  // se questo elemento è uguale a quello che stai calcolando allora non                         fare niente
               else
                   if( m[i][j]==m[p][q])
                         rip++;
            }
     }
    
  • Re: Ricerca occorrenze in matrice

    Anzi ora che ci penso quello che ti ho scritto può essere sbagliato perchè ti faccio fare più cicli inutili , quindi è meglio iniziare dalla posizione i e j ^^. Comunque penso che la funzione ePresente non serva più di tanto perchè fai fare solo più cicli quando invece ne fai solo uno in conta ( uno inteso come due for xD ) . Penso ti basti solo una funzione che ti restituisca true se il valore esiste nel vettore altrimenti false e se non esiste nel vettore allora li conti e se il conta risulta essere > 0 allora esiste una occorrenza e la inserisci nel vettore. Di conseguenza prevedo una funzione conta che restituisca un intero ( in questo modo non devi passare come parametro rip ). Non so se sono stato chiaro , altrimenti ti faccio una bozza
  • Re: Ricerca occorrenze in matrice

    
    void calcolaOccorrenzeInMatrice(matrice m,int r,int c, vettore & v,int & riemp_v){
       
         int occ=0;
         int cont;
         for (int i=0;i<r;i++)
         {
             for (int j=0;j<c-1;j++)
                 if( !ePresente(m[i][j],v,riemp_v) ) // se il valore non è presente nel vettore esegui l' istruzione
                 {
                	cont = conta(m,r,c,i,j); // conta il numero di occorrenze
                    if ( cont > 0 ) // se > 0 allora inserisce nel vettore
                    {
                        v[riemp_v].val=m[i][j];
                        v[riemp_v].occ=cont;
                        riemp_v++; // incrementa il riempimento del vettore
                    }
                 }
         }
         for (int i=0;i<riemp_v;i++)
         cout<<" \n L'elemento "<<v[i].val<<" si ripete "<<v[i].occ<<" volte ";
    }
    
    bool ePresente(int numero,vettore v, int riemp_v){
         
       for ( int i = 0 ; i < riemp_v ; i++)
    	   if ( numero == v[i].val )
    		   return true;
       return false;   
    }
    
    
    int conta(matrice m,int r,int c,int i, int j){
        int rip=0;
        for(int p=i;i<r;i++)
           for (int q=j;j<c;j++)
              if(m[i][j]==m[p][q])
                   rip++;
        return rip;
    }
    
    Non ho compilato nè niente, è giusto per farti capire l' idea che ho in mente .
  • Re: Ricerca occorrenze in matrice

    Beh effettivamente non avevo compilato è stato una cosa che ho buttato giù . Comunque io gli passo
    
    !ePresente(m[i][j],v,riemp_v)
    
    Nel tuo
    
    bool ePresente (matrice m,int r,int c,int i,int j,vettore v,int rpm)
    .....
     while (!ePresente (m,r,c,i,j,rpm)) 
    
    sbagli a passargli i parametri , ti sei dimenticato di passargli il vettore.
  • Re: Ricerca occorrenze in matrice

    Ho provato così:
    
    void ricercaOccorrenze(matrice m,int r, int c, int i, int j,vettore & v,int & rpm){
         rpm=0;
           for(int i=0;i<r;i++){
                  for (int j=0;j<c;j++){ //per ogni elemento della matrice
                  int occ=0;
                        while (!ePresente (m,r,c,i,j,v,rpm)){// se non è presente nell'array degli elementi ripetuti
                               for(int p=0;p<r;p++)
                                       while(j<c-1)
                                            for (int q=j+1;q<c;q++)
                                                     if (m[i][j]==m[p][q]){
                                                      occ++;
                                                       v[rpm].val=m[i][j];
                                                       v[rpm].occ=occ;
                                                       rpm++;
                                                     }
                                                     cout<<prova;//<--------------------------non entra nel ciclo 
                        } 
                  }
           }
           for ( int i=0;i<rpm;i++)
           cout<<v[i].val;
    }
    
    
    bool ePresente (matrice m,int r,int c,int i,int j,vettore v,int rpm){
        
        for (int i=0;i<rpm;i++)
        if (v[i].val==m[i][j])
        return true;
        return false;
    }
    
    ma dove segnalato, non entra nel ciclo
  • Re: Ricerca occorrenze in matrice

    Cerca di indentare meglio tipo così , in modo tale che capisci il cout<<prova ( ma poi prova dove è dichiarato? ) in quale blocco di istruzione si trova e se l' hai messo nel posto dove volevi
    
    void ricercaOccorrenze(matrice m,int r, int c, int i, int j,vettore & v,int & rpm){
         rpm=0;
         for(int i=0;i<r;i++)
         {
             for (int j=0;j<c;j++)
             { //per ogni elemento della matrice
                  int occ=0;
                  while (!ePresente (m,r,c,i,j,v,rpm))
                  {// se non è presente nell'array degli elementi ripetuti
                      for(int p=0;p<r;p++)
                            while(j<c-1)
                                for (int q=j+1;q<c;q++)
                                       if (m[i][j]==m[p][q])
                                       {
                                            occ++;
                                            v[rpm].val=m[i][j];
                                            v[rpm].occ=occ;
                                            rpm++;
                                       }
                      cout<<prova;//<--------------------------non entra nel ciclo 
                  } 
             }
         }
         for ( int i=0;i<rpm;i++)
             cout<<v[i].val;
    }
    
    Forse non hai capito bene la funzione ePresente come l' ho definita io:
    allora il programma l' ho pensato così : Per ogni elemento [j] della matrice controlla se si trova nel vettore v ( questa è la funzione ePresente ) , se non si trova allora conta quante occorenze trova rispetto al valore [j] , se il conta è > 0 ( e quindi ha trovato almeno una occorrenza ) allora lo inserisce nel vettore v e incrementa il riemp.
    
     while (!ePresente (m,r,c,i,j,v,rpm))
    

    perchè un while ? il controllo per ogni elemento lo deve fare una volta quindi penso sia corretto if.
  • Re: Ricerca occorrenze in matrice

    Guarda ho provato su un array
    
    void calcolaOccorrenze(vettore v,int r, int i, vett & v2,int & rpm){
                        bool riemp = false;
                        bool inserisci =false;
                        rpm=0;   
                        for ( i=0;i<r-1;i++){
                              int occ=0;
                         if(!ePresente( v, r, i, v2,rpm))
                            for (int j=i+1;j<r;j++){
                                if (v[i]==v[j]){
                                   cout<<v[i]<<" occ++\n";
                                    inserisci=true;
                                    riemp=true;
                                    occ++;
                                    }
                                if (inserisci)<--------------------// questi due mi danno problemi, ma non capisco il motivo
                                v2[rpm].val=v[i];
                                v2[rpm].occ=occ;
                                if(riemp)<-------------------------
                                rpm++;
                                
                            }
                            
                        }    
                for (int p=0;p<rpm;p++)
                cout<<v2[p].val;    
                      
    }
    
    
    bool ePresente(vettore v, int r, int i,vett v2,int rpm){
         for ( int p=0;p<rpm;p++)
         if (v2[p].val==v[i]){
             return true;
         }
         
         return false;
         
         }
    
    funziona al 30% nel senso che il problema adesso sta nell'aumento di rpm e inserisci
Devi accedere o registrarti per scrivere nel forum
44 risposte