Array considerato ad anello in C

di il
19 risposte

Array considerato ad anello in C

Devo svolgere questo programma:
http://www.roma1.infn.it/people/barone/labcalc/Esercitazione-4-2013-14.pdf

Ma mi sono bloccato cosi;
#include <stdio.h>
#include <stdlib.h>
#define MAX 100
int main()
{
int life[MAX],N,T,i,j,newlife[MAX],temp;

do{
     printf("Inserire un numero positivo minore uguale di 100\n");
     scanf("%d",&N);
   } while(N <= 0 || N> 100);
   
      for(i = 0; i<=N; i++)
        {
         life[i] = 0;
        } 
        life[81]=1;
        life[24]=1;
        life[62]=1;
        
          do{
             printf("Inserire un numero positivo minore uguale di 1000\n");
             scanf("%d",&T);
            } while(T<=0 || T>1000);
             
               for (i=0;i<T;i++)
                  {
                    for(j=0;j<100;j++)
                      {
                          if ((life[j+1] && life[j-1])==1)
                             {
                                 newlife[j]=0;
                             } 
                          if ((life[j+1] || life[j-1])==1)
                             {
                                 temp = newlife[j];
                                 newlife[j]=temp + 1;
                             }  
                          if ((life[j+1] && life[j-1])==0)
                             {
                                 temp = newlife[j];
                                 newlife[j]=temp;
                             }        
                      }
                  }   
return 0;
}
Il problema è che non capisco come fare per far diventare l'array "ad anello"

19 Risposte

  • Re: Array considerato ad anello in C

    Semplicemente per life[0] la sinistra è life[99] e per life[99] la destra è life[0]
  • Re: Array considerato ad anello in C

    Questo era chiaro, ma come lo devo scrivere, e in quale parte del ciclo?
  • Re: Array considerato ad anello in C

    Di certo non puoi andare a modificare il valore di j. Direi che l’operatore condizionale ternario è quello che serve qui…
  • Re: Array considerato ad anello in C

    Credo di aver terminato il programma:
    #include <stdio.h>
    #include <stdlib.h>
    
    #define MAX 100
    int main()
    {
    int life[MAX],N,T,i=0,j,newlife[MAX],temp;
    
    do{
       printf("Inserisci un numero N, 1<=N<=100\n");
       scanf("%d",&N);
      }while(N <= 0 || N> 100);
       
          for(i = 0; i<=N; i++)
            {
             life[i] = 0;
            } 
            life[81]=1;
            life[24]=1;
            life[62]=1;
            
              do{
                 printf("Inserire un numero positivo minore uguale di 1000\n");
                 scanf("%d",&T);
                } while(T<=0 || T>1000);
                   int population[MAX]={0};
                   for (i=0;i<T;i++)
                      {
                        for(j=0;j<100;j++)
                          {
                             if ((j+1) == (MAX+1))
                                 {
                                   life[j+1] = life[0];
                                 }
                               else if ((j-1) == (-1))
                                 {
                                   life[j-1] = life[0];
                                 }
                              if ((life[j+1] && life[j-1])==1)
                                 {
                                     newlife[j]=0;
                                 } 
                              if ((life[j+1] || life[j-1])==1)
                                 {
                                     temp = newlife[j];
                                     newlife[j]=temp + 1;
                                 }  
                              if ((life[j+1] && life[j-1])==0)
                                 {
                                     temp = newlife[j];
                                     newlife[j]=temp;
                                 } 
                              if (newlife[j]==1 || life[j]==1)
                                 {
                                     population[i]++;
                                 }
                          }
                         for (j=0;j<100;j++)
                            {
                                printf("newlife[%d]=%d\n",j,newlife[j]);
                                printf("\n");
                                life[j] = newlife[j];
                                newlife[j]=0;
                            }
                      }   
    return 0;
    }
    E' rimasta incompleta la richiesta di cercare minimo, massimo e ultimo valore di population, qualche idea sul come farlo?
  • Re: Array considerato ad anello in C

    La scelta dei tre punti "a caso" non può voler dire che hai fatto una scelta una volta nella vita e quella rimane nei secoli dei secoli...

    Usa rand() e srand() come fanno tutti
  • Re: Array considerato ad anello in C

    [CODE]if ((j + 1) == (MAX +1) if ((j - 1) == (-1)) Concorderai con me che è equivalente a if (j == MAX) e if (j == 0).
    E comunque una soluzione con ?: sarebbe più pulita.

    E come dice Weierstrass utilizza rand(), magari con un seed controllato per aiutare il debug.

    Si tratta di trovare il minimo e massimo in un array, operazione lineare. Prima ovviamente va dichiarato l’array population.

    Cerca di indentare bene il codice, dichiara le variabili quando ti servono (soprattutto quelle dei cicli) a meno che tu stia usando C89…
  • Re: Array considerato ad anello in C

    Il programma ultimato è questo:
    ci sono però diversi problemi, per esempio i valori di newlife che stampa sono tutti 1 e non mi stampa max e min. come mai?
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #define MAX 100
    int main()
    {
    int life[MAX],N,T,i=0,j,newlife[MAX],temp,casuale1,casuale2,casuale3,seed;
    seed = time(NULL);
    srand(seed);
    
    do{
       printf("Inserisci un numero N, 1<=N<=100\n");
       scanf("%d",&N);
      }while(N <= 0 || N> 100);
       
          for(i = 0; i<=N; i++)
            {
             life[i] = 0;
            } 
            
            
              do{
                 printf("Inserire un numero positivo minore uguale di 1000\n");
                 scanf("%d",&T);
                } while(T<=0 || T>1000);
                   int population[MAX]={0};
                   for (i=0;i<T;i++)
                      {
                          casuale1 = rand()%100;
                          casuale2 = rand()%100;
                          casuale3 = rand()%100;
                          life[casuale1]=1;
                          life[casuale2]=1;
                          life[casuale3]=1;
                        for(j=0;j<100;j++)
                          {
                             if ((j) == (MAX-1))
                                 {
                                   life[j+1] = life[0];
                                 }
                               else if ((j) == (0))
                                 {
                                   life[j-1] = life[MAX-1];
                                 }
                              if ((life[j+1] && life[j-1])==1)
                                 {
                                     newlife[j]=0;
                                 } 
                              if ((life[j+1] || life[j-1])==1)
                                 {
                                     temp = newlife[j];
                                     newlife[j]=temp + 1;
                                 }  
                              if ((life[j+1] && life[j-1])==0)
                                 {
                                     temp = newlife[j];
                                     newlife[j]=temp;
                                 } 
                              if (newlife[j]==1 || life[j]==1)
                                 {
                                     population[i]++;
                                 }
                          }
                         for (j=0;j<100;j++)
                            {
                                printf("newlife[%d]=%d\n",j,newlife[j]);
                                printf("\n");
                                life[j] = newlife[j];
                                newlife[j]=0;
                            }
                      }  
                               int min=population[0];
                               int max=population[0];
                               for(i=0;i<MAX;i++)
                               {
                                  if(population[i] > max)
                                    {
                                       max = population[i];
                                    }  
                               } 
                               for(i=0;i<MAX;i++)
                               {
                                  if(population[i] < min)
                                    {
                                       min = population[i];
                                    }  
                               } 
                               
    printf("Il massimo valore di population[] e': %d\n",max);
    printf("Il massimo valore di population[] e': %d\n",min);
    return 0;
    }
    Inoltre mi chiedevo, per stampare l'ultimo valore di population è sufficiente scrivere:
    printf("L'ultimo valore di population[] e': %d\n",population[MAX-1]);
  • Re: Array considerato ad anello in C

    Perfavore, indenta bene il codice sennò non capisco nulla.
    population va di dimensione MAX? Sei sicuro?
    Una volta chiarita sta cosa credo sia chiaro come stampare l’ultimo elemento…

    E piuttosto che casuale1, casuale2, casuale3, casuale62713829 un normale ciclo for no? [CODE] for (int i = 0; i < 3; i++) life[rand() % 100] = 1; E resterebbe il problema che rand() % 100 potrebbe essere un valore già uscito, quindi questo for andrebbe migliorato, vedi tu come
  • Re: Array considerato ad anello in C

    L'inizializzazione di life la puoi fare semplicemente con = {0}, così come hai fatto per population.
    Il for che fai è comunque sbagliato, perché con i<= N, se N = 100, vai a scrivere un valore fuori dall'array.

    Il sorteggio con rand() deve essere fatto finché i tre valori casuali risultino diversi tra loro.

    MAX la dichiari come macro ma poi usi i 100 nel codice.

    Il resto del codice sembra troppo complicato per quello che ti viene richiesto

    Capisco che ti sembrino pignolerie e scocciature, ma d'altro canto ti sei iscritto a fisica mi pare... se non sei pignolo fin da subito che farai più avanti?
  • Re: Array considerato ad anello in C

    Oltre alle cose che ti sono state fatte notare nei precedenti 2 post:
    - chiedi all'utente di inserire N e poi non la utilizzi?
    - l'array population è inutile, bastano le variabili min e max;
    - utilizzando i puntatori puoi evitare di aggiornare di volta in volta l'array life;
    - in ogni caso cmq l'intera struttura logica del programma è completamente sbagliata, quindi è ovvio che non funzioni!

    P.S.
    - con un po' di logica puoi ottenere il numero di 0 adiacenti al generico elemento life[j] utilizzando un'unica istruzione del tipo
    int numero_di_0_adiacenti = ...;
  • Re: Array considerato ad anello in C

    @NIppolo A me N sembra utilizzata per il suo scopo....
    Comunque l'array population è richiesto dal testo, il quale non chiede quello che hai scritto (il numero di 0 adiacenti al generico elemento life[j]).
    Comunque se ti sembra sbagliata la struttura logica magari fammi presente dove e come sistemare
    @Weierstrass fai bene ad essere pignolo, tranquillo
  • Re: Array considerato ad anello in C

    Nexus99 ha scritto:


    @NIppolo A me N sembra utilizzata per il suo scopo....
    Devi considerare i primi N elementi (dei MAX disponibili) sempre e non solo quando inizializzi i valori a 0. Magari nel testo non è scritto in modo esplicito, ma la tua interpretazione non avrebbe alcun senso. Tra l'altro ti ritroverai che gli elementi di indice appartenente all'intervallo [N;MAX) avranno dei valori casuali, in quanto mai inizializzati.

    Nexus99 ha scritto:


    Comunque l'array population è richiesto dal testo
    Lo so, fatto sta che resta inutile!

    Nexus99 ha scritto:


    il quale non chiede quello che hai scritto (il numero di 0 adiacenti al generico elemento life[j]).
    Non in modo esplicito, ma conoscendo il numero di 0 (che potrà essere 0, 1 o 2) adiacenti al generico elemento life[j], dalla consegna si deduce che:
    - 2 zeri ==> newlife[j] sarà uguale a life[j];
    - 1 zeri ==> newlife[j] sarà diverso da life[j];
    - 0 zeri ==> newlife[j] sarà 0.
    Il che ti permette di semplificare il codice evitando di utilizzare una marea di if/else.

    Nexus99 ha scritto:


    Comunque se ti sembra sbagliata la struttura logica magari fammi presente dove e come sistemare
    Inizia ad aggiustare il codice seguendo i vari consigli che ti sono stati forniti, compreso quelli relativi alla leggibilità dello stesso (consigli che ti ho dato anche nel topic della roulette)!
  • Re: Array considerato ad anello in C

    Dei miglioramenti che mi avete consigliato alcuni sono stati apportati, altri non sono riuscito, ovviamente il programma continua a non funzionare, boh sarà che sono negato
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #define MAX 100
    int main()
    {
    int life[MAX]={0},N,T,i=0,j,newlife[MAX],temp,seed,casuale1,casuale2,casuale3;
    seed = time(NULL);
    srand(seed);
    
    do{
       printf("Inserisci un numero N, 1<=N<=100\n");
       scanf("%d",&N);
      }while(N <= 0 || N> MAX);
        
    do{
        printf("Inserire un numero positivo minore uguale di 1000\n");
                 scanf("%d",&T);
      } while(T<=0 || T>1000);
        int population[MAX]={0};
    for (i=0;i<T;i++)
      {
          
              casuale1 = rand() % 100;
              casuale2 = rand() % 100;
              casuale3 = rand() % 100;
              life[casuale1] = 1;
              life[casuale2] = 1;
              life[casuale3] = 1;
              if ((casuale1)==(casuale2))
              {
                  casuale1+=1;
              }
              else if ((casuale1)==(casuale3))
              {
                  casuale1+=1;
              }
              else if ((casuale2)==(casuale3))
              {
                  casuale3=casuale2+2;
              }
            
            for(j=0;j<N;j++)
            {
              if ((j) == (N-1))
                 {
                   life[j+1] = life[0];
                 }
              else if ((j) == (0))
                 {
                   life[j-1] = life[N-1];
                 }
              if ((life[j+1] && life[j-1])==1)
                 {
                   newlife[j]=0;
                 } 
              if ((life[j+1] || life[j-1])==1)
                 {
                   temp = newlife[j];
                   newlife[j]=temp + 1;
                 }  
              if ((life[j+1] && life[j-1])==0)
                 {
                   temp = newlife[j];
                   newlife[j]=temp;
                 } 
              if (newlife[j]==1 || life[j]==1)
                 {
                   population[i]++;
                 }
            }
            for (j=0;j<N;j++)
            {
              printf("newlife[%d]=%d\n",j,newlife[j]);
              printf("\n");
              life[j] = newlife[j];
              newlife[j]=0;
            }
      }  
    int min=population[0];
    int max=population[0];
    for(i=0;i<N;i++)
    {
      if(population[i] > max)
       {
         max = population[i];
       }  
    } 
    for(i=0;i<N;i++)
    {
      if(population[i] < min)
        {
           min = population[i];
        }  
    } 
                               
    printf("Il massimo valore di population[] e': %d\n",max);
    printf("Il massimo valore di population[] e': %d\n",min);
    printf("L'ultimo valore di population[] e': %d\n",population[MAX-1]);
    return 0;
    }
    
  • Re: Array considerato ad anello in C

    Iniziamo dalla parte che si occupa di settare 3 elementi casuali di life ad 1. Innanzitutto le variabili casuale1, casuale2, casuale3 sono inutili, infatti come già ti è stato detto basta utilizzare un semplice ciclo for. Quello che devi fare è generare un numero casuale (chiamiamolo r) compreso nell'intervallo [0;N) (e non [0;MAX)), controllare se l'elemento life[r] è uguale a 0 e in tal caso settarlo a 1.

    Per quanto riguarda la dimensione dell'array population (che come già detto più volte è completamente inutile), se ci rifletti bene non è data da MAX... in pratica la popolazione (ossia il numero di 1) viene calcolata ad ogni generazione di newlife, quindi l'array population deve avere una dimensione pari al numero di volte in cui viene generato newlife.

    Perchè due for distinti per calcolare min e max?

    Veniamo ora al cuore del programma, ossia la parte che si occupa di generare newlife. Piccolo spoiler... è completamente sbagliata!
    Consideriamo il seguente frammento
    if ((j) == (N-1))
    {
    	life[j+1] = life[0];
    }
    Se j==N-1 ==> j+1=N-1+1=N ==> che andrai a scrivere in life[N], che è un settore di memoria che non compete all'array.
    Consideriamo il seguente frammento
    else if ((j) == (0))
    {
    	life[j-1] = life[N-1];
    }
    Se j==0 ==> j-1=0-1=-1 ==> che andrai a scrivere in life[-1], che non ha proprio senso.
    Consideriamo il seguente frammento
    if((life[j+1] && life[j-1])==1)
    {
    	newlife[j]=0;
    }
    è corretto, ma temo che si tratti di una fortunata coincidenza! In pratica la condizione che hai scritto non controlla che life[j+1] e life[j-1] siano entrambi 1, ma controlla che siano entrambi diversi da 0. In pratica volendo dilungarsi la suddetta condizione può essere riscritta come
    if((life[j+1] != 0 && life[j-1] != 0) == true)
    volendo invece essere più concisi
    if(life[j+1] && life[j-1])
    Consideriamo il seguente frammento
    if ((life[j+1] || life[j-1])==1)
    {
    	temp = newlife[j];
    	newlife[j]=temp + 1;
    }
    innanzitutto da un punto di vista logico, affinché la cosa funzioni dovresti sostituire l'if con un ifelse, altrimenti se sarà vero l'if precedente lo sarà per forza di cose anche questo. Quell'utilizzo di temp non ha alcun senso in quanto le istruzioni
    temp = newlife[j];
    newlife[j]=temp + 1;
    coincidono con
    newlife[j]++;
    In ogni caso stando alla traccia qui ci troviamo nel caso in cui life[j] ha il valore 1 o solo a destra o solo a sinistra, quindi all'interno dell'ifelse andrebbe messo
    if(life[j]==0)
    {
    	newlife[j]=1;
    }
    else
    {
    	newlife[j]=0;
    }
    o molto più semplicemente, sfruttando l'algebra booleana
    newlife[j]=!life[j];
    Non vado oltre in quest'analisi dettagliata del codice, ma spero che tu riesca da solo a trovare glia altri errori.

    Ti riporto infine un frammento di un mio post nel topic della roulette:
    - innanzitutto al fine di rendere il codice più chiaro e leggibile, ti consiglio di rispettare la spaziatura e l'indentazione e di scrivere una sola istruzione per riga;
    - ti conviene ripassare un po' la precedenza fra gli operatori in modo da evitare di mettere parentesi tonde lì dove non servono;
Devi accedere o registrarti per scrivere nel forum
19 risposte