Problema codice vettore multidimensionale

di
Anonimizzato23166
il
10 risposte

Problema codice vettore multidimensionale

Salve a tutti
ho un problema con un programma.
il codice stampa una serie di righe di zeri e la lunghezza delle righe e' variabile.
scegliendo n all inizio del codice scelgo il numero delle righe dopodiche inserisco da tastiera la lunghezza delle colonne.
poi stampo e fin qui tutto bene.

questo oggetto *vv e' inizializzato nel modo seguente (inserisco solo gli indici) supponendo di avere scelto n=3 e aver inserito da tastiera successivamente 4,5,6.

0-2 0-3 0-4

1-2 1-3 1-4 1-5

2-2 2-3 2-4 2-5 2-6

il risultato della prima stampa e'

0 0 0
0 0 0 0
0 0 0 0 0

fin qui tutto bene.

successivamente voglio fare in modo che in corrispondenza degli indici multipli di 2 (escludendo il 2) per ogni riga il valore da 0 diventi 1 quindi in questa situazione mi aspetto di trovare

0 0 1
0 0 1 0
0 0 1 0 1

invece trovo questo

0 0 1
0 0 1 0
1 0 1 0 1

in altre situazioni le cose vanno al loro posto e in altre ancora no.
posto il codice e se qualcuno ha qualche idea sarebbe un grosso aiuto.
grazie in anticipo

#include <stdio.h>
#include <math.h>
#define N 1000

int numero (int *nn) {
int i,n;

while(n<2)                        {
printf("n deve essere >=2\n");
printf("inserisci il numero di interi che vuoi considerare\n");
scanf("%d",& n);                  }
     
     
printf("inserisci il singolo elemento\n");

for (i=0;i<n;i++)   
scanf("%d",& nn[i]);  
          
//printf("\n");
          /*
for (i=0;i<n;i++)
printf("%d\n",nn[i]); 
         */
return n;

                     }

int insert(unsigned long int **v,int nn[],int n) {  //passaggio vettore di puntatori; vettore di interi e parametro n  
 	int i,j,a,r;
 	
  	printf("controlliamo se n e' >= 2 e in tal caso procediamo\n");
  	printf("2 e' l unico numero primo pari, per controllare se n e' primo basta vedere se nella colonna dei numeri primi generati\n");
  	printf("l ultimo numero coincide con n, se coincide il numero e' primo altrimenti non lo e'\n");
  	printf("controlliamo se n e' pari o dispari\n");
  	printf("troviamo i numeri primi <= di n con il Crivello di Eratostene\n");	
  	printf("attenzione se inserisci un numero con il punto o con la virgola il codice\n");
  	printf("va in loop e per fermarlo occorre premere ctrl+c e ricompilarlo per ripartire\n\n\n\n");
  	   
  	   for(r=0;r<n;r++)  {
  	   
  	        a = sqrt (nn[r]);
  	        if(nn[r]==a*a)
  	        printf("il numero %d e' un quadrato perfetto\n",nn[r]);
  	
  		if (nn[r]%2 == 0)
  		printf("il numero %d e' positivo e pari\n",nn[r]);
  		else
  		printf("il numero %d e' positivo e dispari\n",nn[r]);
                printf("\n");
                              
 /*generiamo un vettore di zeri*/
                             }
  
                             /*
  for(r=0;r<n;r++)  {
                  printf("%d\t%d\n",n,nn[r]);
                  }
                                            printf("\n\n");
                               */
  	for(i=0; i<n; i++)     {              
  	for(j=2; j<=nn[i]; j++)
  		v[i][j]=0;      }
                    
                             
        for(i=0; i<n; i++)  {                 
  	for(j=2; j<=nn[i]; j++)
                    
                    printf("%lu\t",v[i][j]);   
                    printf("\n");
                             }
                   }



void eratostene(unsigned long int **v, int nn[], int n) {
  	int i,j,k;
  	
  		
  	for (i=0;i<n;i++)        {
  	
 	for(j=2; j<=nn[i]; j++)                     
	
		      for(k=2*j; k<=nn[i]; k+=j) 
					    
    				v[i][k]=1;           
    			
  	                               }
  	                                      
                    printf("\n\n");
  	
  	            
        for(i=0; i<n; i++)  {                 
  	for(j=2; j<=nn[i]; j++)
                    
                    printf("%lu\t",v[i][j]);   
                    printf("\n");
                             }
  	
  	
  	                                             }
    				        
    				  
                               

int main() {

         int n,nn[N],**q,z[N],w[N];
         unsigned long int **v;
//for (r=0;r<n;r++)	{

	n=numero(nn);
	
	insert(v,nn,n);
	eratostene(v,nn,n);
//	print(v,nn,n);
//	primo(v,q,nn,n);
//	terzo(q,z,nn,n);
//	quarto(z,w,nn,n);
  //      quinto(c,e,n);
    //    sesto(c,e,x,n);
      //  ottavo(x,n);
    
//        nove(b,c,x,d,n,l);
  //      dieci(u,e,x,n);
   //                    }
          
  return 0; }

 				  
    				                

10 Risposte

  • Re: Problema codice vettore multidimensionale

    Premesso che non ho letto il codice, ma ho solo intravisto la parola eratostene, mi viene da dire una cosa: non sempre l'algoritmo che ci viene in mente è il migliore per il problema che ci siamo prefissati di risolvere.
    Detto questo, se il tuo scopo è quello di implementare il crivello di eratostene, ci sono strade molto più semplici per farlo. E in ogni caso l'intero post, che presumo abbia a che fare con l'algoritmo da te ideato per implementare il crivello, non è per nulla chiaro.
  • Re: Problema codice vettore multidimensionale

    Credo di avere un illuminazione.
    credo che l incremento di k ossia k+=j nella situazione sopra indicata mi faccia mettere 1 in corrispondenza dell elemento di posizione 2-2 poiche' k posiziona 1 all'elemento 1-6 della riga 2 ma siccome la nuova riga ossia la 3 che comincia con 2-2 (ossia cella 1-6 a cui punta la variabile puntatore) viene sovrascritta con 1 e quindi mi tro quell'uno nella terza riga.
    quindi credo che la soluzione sia costruire una matrice piena mettendo gli zeri nelle posizioni mancantiper evitare di incappare nella situazione sopra.
    sono solo ipotesi, non ho avuto modo di confermarle.
    se qualcuno puo darmi una mano sarebbe un grosso aiuto.
    PS questa parte di codice deriva da uno che ho fatto tempo fa e quello funziona benissimo solo che lavora solo con un numero quindi la mia matrice e' solo 1xn
  • Re: Problema codice vettore multidimensionale

    Grazie per la risposta.
    hai ragione meglio fare un po di chiarezza.
    allora parto dal fatto che in un programma che posto qui sotto il mio scopo e' molteplice.
    il primo e' quello di trovare i numeri primi in un intervallo da 2 ad n con n inserito da tastiera.
    una volta trovati i numeri primi il codice permette di trovare i fattori di n che nel caso sia primo sono solo 2
    il codice inoltre calcola le differenze tra due numeri primi successivi.
    il codice ad un certo punto chiede di inserire un ulteriore parametro che rappresenta l intervallo aperto tra due primi e quindi impostando questo parametro posso stampare ad esempio la successione dei primi gemelli o altre successioni di primi con diversi intervalli aperti di separazione.

    nel nuovo codice che sto implementando vorrei avere la possibilita' di ricercare i numeri primi tra 2 ed n per diversi valori di n in pratica e' come ripetere la ricerca n volte ed ottenere n diversi output.
    PS mi sapresti suggerire una strada piu' semplice per implementare Eratostene?
    ecco il codice iniziale
    
    #include <stdio.h>
    #include <math.h>
    #define N 5000
    
    int insert(int *v) {    
     	int i, n, a;
     	
      	
      	printf("controlliamo se n e' >= 2 e in tal caso procediamo\n");
      	printf("2 e' l unico numero primo pari, per controllare se n e' primo basta vedere se nella colonna dei numeri primi generati\n");
      	printf("l ultimo numero coincide con n, se coincide il numero e' primo altrimenti non lo e'\n");
      	printf("controlliamo se n e' pari o dispari\n");
      	printf("troviamo i numeri primi <= di n con il Crivello di Eratostene\n");	
      	printf("attenzione se inserisci un numero con il punto o con la virgola il codice\n");
      	printf("va in loop e per fermarlo occorre premere ctrl+c e ricompilarlo per ripartire\n\n\n\n");
      	
      	while (n<2) {
      	printf("il numero n deve essere >=2; inserisci n--- ");
      	scanf("%d", &n);
      	             }
      	
      	        a = sqrt (n);
      	        if(n==a*a)
      	        printf("il numero %d e' un quadrato perfetto\n",n);
      	
      		if (n%2 == 0)
      		printf("il numero e' positivo e pari\n");
      		else
      		printf("il numero e' positivo e dispari\n");
                    printf("\n");
    
     /*generiamo un vettore di zeri*/
      	for(i=2; i<=n; i++)
      		v[i]=0;
       
      	return n;
                       }
    
    
    
    void eratostene(int *v, int n) {
      	int i,j;
      	
     	for(i=2; i<=n; i++)
    //		if(v[i]==0)
        		         for(j=2*i; j<=n; j+=i) 
    					    
        				v[j]=1;			//let's set v[j]=1, to mark all the multiple number ; that's the sieve 
        				                }
        				        
        				                
    void print(int *v, int n) {
    	int i,k;
    	
    	k=0;
       for(i=2; i<=n; i++) 
       if(v[i]==0) //if the number is prime
       k=k+1;  //count the number of prime numbers
       printf("\nnumeri primi compresi tra 2 e %d sono %d:\n\n",n,k);  
    
    
                                 for(i=2; i<=n; i++) 
                                 printf("%d\t",v[i]);
    
    
    
                                 }
                              
     void primo (int *v, int *q,int n)		{//memorizzo i primi nel vettore q[i] ma contiene anche gli zeri
     			int i,j;
     			
     		 for(i=2; i<=n; i++)   
    		 if(v[i]==0)
    	                                                    
    		 q[i]=i;  //vettore che contiene i numeri primi e gli zeri come distanze
    		 
    		                                  }
    
    void terzo (int *q,int *z,int n)    {  //creo un nuovo vettore di primi senza gli zeri
                     int i,j,M,flag;
                     
                     
                     M=0; //dimensione nuovo vettore
                     
                     for(i=2; i<=n; i++) 
                     if(q[i]!=0)         {
    			    flag=0;   
    			    
    			    
    		for(j=0;j<=M ;j++)   
    		if(z[j]==q[i])
    			    flag=1;           
    
                                         
    		if(flag==0)     
    		z[M]=q[i];     
    		M=M+1;         
    				}//chisura ciclo if
                              printf("numeri primi memorizzati in un vettore\n");  //ho eliminato gli zeri da q nel vettore z
                                             for(i=0; i<M; i++) 
                                                 printf("%d\t",z[i]);
                              
                                       }
    
    
                                    
    void quarto (int *z,int *w)    {  //trovo il vettore delle differenze tra due numeri primi successivi
                     int i,j,M;  
                     printf("\n\n");
                     printf("vettore differenze tra due primi successivi\n");
                     for(i=0; i<M; i++) {
                     w[i]=z[i+1]-z[i];  }
                     
                    // printf("\nvettore delle distanze ossia intervalli aperti tra due primi successivi\n");
                     
                     for(i=0; i<M-1; i++)   {
                     printf("%d\t",w[i]); }
    
                                        }
    
    void quinto (int *z,int *f,int n) {    //funzione che memorizza i fattori di n inclusi gli zeri in un vettore f
                    
                     int i,j,M,flag;
                     
                					     printf("\n");
                                                         printf("stampiamo i fattori primi di %d\n",n);
                                                         
                    	                             for(i=0; i<M; i++) {
                    	                             if(n%z[i]==0)
                    	                             f[i]=z[i];
                                                                            } 
                                             }
    
        
    void sesto (int *z,int *f,int *g,int n) {
                     int i,j,L,M,flag,k;
                     
                      L=0; //dimensione nuovo vettore
                     
                     for(i=0; i<n; i++) 
                     if(f[i]!=0)         {
    			    flag=0;   
    			    
    		for(j=0;j<=L ;j++)   
    		if(g[j]==f[i])
    			    flag=1;           
                                         
    		if(flag==0)     
    		g[L]=f[i];     
    		L=L+1;                //L e' la dimensione del vettore che contiene i fattori di n senza gli zeri
    				}//chisura ciclo if
                             // printf("\nfattori primi memorizzati in un vettore\n");  //ho eliminato gli zeri da f
                                             for(i=0; i<L; i++) {
                                                 printf("%d\n",g[i]);}
    
                                                                              }
    
    void ottavo (int *g,int n) { //funzione che stampa gli esponenti dei fattori primi
    
                     int i,k,tmp,t;
    
                    printf("esponenti dei fattori primi\n");
                                
    		for(i=0;i<t;i++){
                    k=0;
                    tmp=g[i];
                    while(n%tmp==0){
                    n=n/tmp;
                    k=k+1;         }
    
                               printf ("%d\n",k);//stampa degli esponenti
                                   }
    
                                      }
    
    
    
    void dieci (int *s,int *f,int *g,int n) { //funzione che ricostruisce n a partire dai fattori e dagli esponenti dei fattori
    
                                int i,j,k,t,tmp,L,flag;                          
                     
                               printf("\n%d = ",n);
                     
                      L=0; 
                     
                     for(i=0; i<n; i++) 
                     if(f[i]!=0)         {
    			    flag=0;   
    			    
    		for(j=0;j<=L ;j++)   
    		if(g[j]==f[i])
    			    flag=1;           
                                         
    		if(flag==0)     
    		g[L]=f[i];     
    		L=L+1;          }  //ricostruisco la dimensione di L per i fattori
    
                                
    		for(i=0;i<L;i++){
                    k=0;
                    tmp=g[i];
                    while(n%tmp==0){
                    n=n/tmp;
                    k=k+1;         
                    s[i]=k;            // memorizzo gli esponenti nel vettore s
                			}
                                    }
                                
                                             for(i=0;i<L;i++)
                                       printf ("%d^%d  ",g[i],s[i]);//stampa del numero n con fattori ed esponenti
                                                   printf("\n");
                                   }
    
    
    void nove (int *q,int *z,int *g,int *w,int n,int r)     {
    
                     int i,j,M,flag;
                                    
                     M=0; //devo ricostruire la dimensione del vettore perche' M e' variabile locale
                     
                     for(i=2; i<=n; i++) 
                     if(q[i]!=0)         {
    			    flag=0;   
    			    
    			    
    		for(j=0;j<=M ;j++)   
    		if(z[j]==q[i])
    			    flag=1;           
    
                                         
    		if(flag==0)     
    		z[M]=q[i];     
    		M=M+1;               }
    				
                                                 printf("\n\n");
                                                 
                                                                                   
    				   while(r<1)        {
                                       printf("il parametro r deve essere >=1;se r=2 (vuol dire r-1 interi nel sub-intervallo r) otteniamo la lista dei numeri primi gemelli\n");
                                       printf("se tutte le coppie di numeri primi <=%d hanno distanza inferiore ad r\n",n);
                                       printf("il codice non genera nessuna coppia e termina\n");   
                                       printf("inserisci qui il parametro r---  ");
      				   scanf("%d", &r);  }
                                                 
                                        for(i=0;i<M;i++) {
                                                 if(w[i]==r)                        
                                                       printf("%d\t%d\n",z[i],z[i+1]); }     
    			    }
    
    int main() {       
    	int a[N],b[N],c[N],d[N],e[N],x[N],y[N],u[N],n,r; //a=v; b=q, c=z; d=w; e=f; g=x; h=y;s=u
    	
    	n=insert(a);
    	eratostene(a,n);
    	print(a,n);
    	primo(a,b,n);
    	terzo(b,c,n);
    	quarto(c,d);
            quinto(c,e,n);
            sesto(c,e,x,n);
            ottavo(x,n);
        
            nove(b,c,x,d,n,r);
            dieci(u,e,x,n);
      return 0; }
    
  • Re: Problema codice vettore multidimensionale

    Innanzitutto al fine di rendere il codice più chiaro e leggibile ti consiglio di:
    - scrivere una sola istruzione per riga;
    - rispettare la spaziatura e l'indentazione;
    - racchiudere sempre il corpo delle istruzioni di controllo all'interno di parentesi graffe;
    - assegnare alle variabili e alle funzioni dei nomi coerenti ed esplicativi;
    - evitare di lasciare inutili spazi vuoti tra una riga e l'altra.
    PS mi sapresti suggerire una strada piu' semplice per implementare Eratostene?
    Io farei qualcosa del genere:
    #include <stdio.h>
    
    #define N 5000
    
    int main()
    {
        int v[N - 1];
        unsigned int i;
        unsigned int j;
        for(i = 0; i < N - 1; ++i)
        {
            v[i] = i + 2;
        }
        i = 0;
        while(1)
        {
            j = v[i] * v[i];
            if(j > N)
            {
                break;
            }
            do
            {
                v[j - 2] = 0;
                j += v[i];
            }
            while(j <= N);
            while(v[++i] == 0);
        }
        printf("NUMERI PRIMI MINORI O UGUALI DI %d: ", N);
        for(i = 0; i < N - 1; ++i)
        {
            if(v[i])
            {
                printf("%d ", v[i]);
            }
        }
        return 0;
    }
    Qual era invece lo scopo di quell'algoritmo di cui parlavi nel post iniziale?
  • Re: Problema codice vettore multidimensionale

    Grazie della risposta.
    dunque lo scopo dell algoritmo di cui parlavo all'inizio e' quello in pratica di ripetere il crivello di Eratostene non su un solo numero come nel codice che ho postato ma sugli elementi interi di un vettore.
    quindi vorrei che questo nuovo codice una volta introdotti ad esempio n1 , n2, n3 mi dicesse i primi tra 2 ed n1, tra 2 ed n2, tra 2 ed n3 e mi desse le stesse informazioni che mi da il codice postato in precedenza su ogni n.
    spero di essermi spiegato; una volta che ottengo ad esempio le tre liste dei numeri primi di n1,n2,n3 (in questo caso) ed i relativi fattori ed esponenti, potrei ad esempio determinare il minimo comune multiplo oppure il massimo comun denominatore oppure ancora creare i relativi alberi oppure....
    insomma molte cose.
    questo in poche parole e' lo scopo del primo codice di cui parlavo all'inizio del thread.
    grazie ancora per il codice da te postato, lo studiero' non appena avro' un minuto libero, magari ci vorra' un po di piu' di un minuto essendo io un po lento di comprendonio, quindi idee anche in questo secondo codice sono ben accette.
    grazie ancora.
  • Re: Problema codice vettore multidimensionale

    Di niente!
    quindi vorrei che questo nuovo codice una volta introdotti ad esempio n1 , n2, n3 mi dicesse i primi tra 2 ed n1, tra 2 ed n2, tra 2 ed n3 e mi desse le stesse informazioni che mi da il codice postato in precedenza su ogni n.
    Scusa, ma non avendo letto tutto il tuo codice non so a cosa ti riferisci quando parli di "informazioni", e non capisco quali informazioni potresti mai trarre dall'applicazione del crivello.
    spero di essermi spiegato; una volta che ottengo ad esempio le tre liste dei numeri primi di n1,n2,n3 (in questo caso) ed i relativi fattori ed esponenti, potrei ad esempio determinare il minimo comune multiplo oppure il massimo comun denominatore oppure ancora creare i relativi alberi oppure....
    Ma il tuo scopo è la scomposizione in fattori primi di un numero? Chiedo perchè in tal caso il crivello di eratostene mi sembra una strada un tantino contorta.

    Se hai qualche dubbio relativo al codice che ho postato, chiedi pure.
  • Re: Problema codice vettore multidimensionale

    Grazie
    la scomposizione in fattori primi di un numero e' quello che il codice postato fa, oltre alle cose che dicevo nel messaggio precedente.
    il crivello per me e' solo uno dei modi per trovare i numeri primi.
    come dicevo in questo nuovo codice non faccio nulla di nuovo sennonche' invece che trovare i numeri primi solo da un intero, vorrei trovare i numeri primi per diversi valori di n.
    se provi a compilare il codice che ho fatto, si capisce subito cosa il codice permette di fare.
    il nuovo codice non da altro che la possibilita' di inserire diversi valori di n e non uno solo.
    io a parte il crivello di Eratostene, il metodo di Fermat, quello di Pollard l' squfof, il cfrac, Pomerance col crivello quadratico, non conosco nessun altro metodo.
    per analizzare il tuo codice dovro' aspettare il finesettimana, se ho qualche problema ti ricontatto.
    per adesso grazie.
    ciao
  • Re: Problema codice vettore multidimensionale

    Stando solo ai nomi non saprei dirti con sicurezza se conosco o meno i vari metodi che hai citato, ma non è questo il punto.
    Quello che intendo dire è che se il tuo scopo è quello di ottenere i numeri primi minori di n e le relative differenze tra numeri primi successivi, allora utilizza pure il crivello di eratostene.
    Se invece lo scopo è la fattorizzazione di n, allora ci sono strade più semplici e meno contorte.

    Dando un'occhiata al codice ho capito l'utilizzo che fai del crivello al fine di ottenere la fattorizzazione di n, ma sei sicuro che questo metodo sia più efficiente di una semplice ricerca dei suoi divisori?
    Potresti per esempio fare qualcosa del genere:
    #include <stdio.h>
    
    int main()
    {
        unsigned int n;
        unsigned int N;
        unsigned int div = 2;
        unsigned int esp = 0;
        printf("n --> ");
        scanf("%d", &n);
        N = n;
        printf("%d =", n);
        while(n / div >= div)
        {
            while(n % div == 0)
            {
                n /= div;
                ++esp;
            }
            if(esp)
            {
                printf("% d", div);
                if(esp > 1)
                {
                    printf("^%d", esp);
                }
                esp = 0;
            }
            div += div % 2 + 1;
        }
        if(n != N)
        {
            if(n != 1)
            {
                printf("%d", n);
            }
        }
        else
        {
            printf(" NUMERO PRIMO");
        }
    }
    Se poi vuoi salvarti il risultato della fattorizzazione basta utilizzare due semplici array in cui andrai ad inserire fattori primi e relativi esponenti.
    Se poi devi fattorizzare parecchi numeri e vuoi ottimizzare il tutto, potresti trovare n_max, calcolarne la radice quadrata, prenderne solo la parte intera (chiamiamola m) e applicare il crivello di eratostene a m salvando tutti i numeri primi <=m in un array v. A quel punto basta sostituire nel codice che ho appena postato la riga
    div += div % 2 + 1;
    con
    div = v[i];
  • Re: Problema codice vettore multidimensionale

    Grazie mille per il codice, vorrei avere la capacita' di sintetizzare il tutto come nel tuo codice, nei miei per arrivare da A a B devo prima fare il giro del mondo.
    ad un primo colpo d'occhio l unica cosa con cui ho problemi e' quando ad esempio nel primo tuo codice nel ciclo while utilizzi come condizione 1, oppure nella if nel tuo secondo codice metti if(esp).
    premetto che non conosco tutti i sofismi delle sintassi del C ed e' probabilmente anche per questo che i miei codici sono cosi' grezzi.
    in ogni caso studiero' con calma i tuoi codici.
    il metodo che uso per cercare di mettere un algoritmo in forma di codice e' quello con carta e penna, e se ottengo il risultato il piu delle volte non mi preoccupo troppo dell'ottimizzazione che nel mio caso date le scarse capacita' richiederebbe troppo tempo anche se devo ammettere che un codice ottimizzato e con meno linee e' molto piu semplice da controllare per un eventuale modifica.
    in ogni caso apprezzo molto l'aiuto.
    grazie ancora.
  • Re: Problema codice vettore multidimensionale

    Di niente.

    Per quanto riguarda le condizioni, semplicemente il C valuta 0 come falso e tutti gli altri interi come vero.
Devi accedere o registrarti per scrivere nel forum
10 risposte