Indice del forum Olimpo Informatico
I Forum di Zeus News
Leggi la newsletter gratuita - Attiva il Menu compatto
 
 FAQFAQ   CercaCerca   Lista utentiLista utenti   GruppiGruppi   RegistratiRegistrati 
 ProfiloProfilo   Messaggi privatiMessaggi privati   Log inLog in 

    Newsletter RSS Facebook Twitter Contatti Ricerca
aiuto su sorgente c
Nuovo argomento   Rispondi    Indice del forum -> Programmazione
Precedente :: Successivo  
Autore Messaggio
marcus905
Mortale devoto
Mortale devoto


Registrato: 12/05/06 21:05
Messaggi: 13

MessaggioInviato: 01 Feb 2007 23:39    Oggetto: aiuto su sorgente c Rispondi citando

non riesco a capire perchè questo programma mi fa sempre un segmentation fault quando lo eseguo. da notarsi che nella compilazione non sputa fuori nessun errore.

Codice:

#include <stdio.h>

main()
{

   int n,elim;
   long int i,j,c;
   int tavolo[501];

   scanf("%d %d", c, n);
   for(i=1;i<=c;i++)
   {
      tavolo[i]=1;
   }
   
   j=1;

   do
   {
      for(i=1;i<=n;i++)
      {
      
         j++;
         if(j==c+1){j=1;}
         if(tavolo[i]==0){i--;}
      
      }

      tavolo[i]=0;
      elim++;
   }
   while(elim!=c-1);
   
   int vincitore;
   
   for(i=1;i<=n;i++)
   {
   
      if(tavolo[i]=1){vincitore=i;}
         
   }
   
   printf("%d\n", vincitore);
}


comunque il programma dovrebbe far questo più o meno:

legge il numero di persone sedute su un tavolo ( 1<=c<=500, incrementato di 1 perche poi dovro far qualcosa con tavolo[0] ) e un numero casuale ( n ).
il programma poi elimina uno ad uno quelli che stanno all'n-esima iterazione (con un incremento per iterazione) non eliminati, e nel caso fossero eliminati provvede a saltare l'elemento, finquando non rimane un solo elemento non eliminato che poi quindi viene stampata su stdout. essendo il tavolo circolare all'ultimo elemento succede il primo, quindi appena j arriva a c+1 torna ad 1.

è il mio primo programma in c dopo anni ed anni di pascal (che piaceva ai miei prof così tanto che oramai quella schermata blu mi faceva sanguinare gli occhi ogniqualvolta la vedevo) e ho notato che sono diventato un po' troppo arrugginito, quindi chiedo umilmente aiuto a voi Grandi Maestri
Top
Profilo Invia messaggio privato
SverX
Supervisor Macchinisti
Supervisor Macchinisti


Registrato: 25/03/02 11:16
Messaggi: 11559
Residenza: Tokelau

MessaggioInviato: 02 Feb 2007 15:43    Oggetto: Re: aiuto su sorgente c Rispondi citando

non capisco il senso di:

Codice:
if(tavolo[i]==0){i--;}


dentro un for con i come indice... forse volevi usare j come indice dell'array?

e poi, viva il Pascal Very Happy
Top
Profilo Invia messaggio privato HomePage
marcus905
Mortale devoto
Mortale devoto


Registrato: 12/05/06 21:05
Messaggi: 13

MessaggioInviato: 02 Feb 2007 16:35    Oggetto: Rispondi citando

già era
Codice:

if(tavolo[j]==0)


refuso, scusate!
Top
Profilo Invia messaggio privato
SverX
Supervisor Macchinisti
Supervisor Macchinisti


Registrato: 25/03/02 11:16
Messaggi: 11559
Residenza: Tokelau

MessaggioInviato: 02 Feb 2007 17:00    Oggetto: Rispondi citando

marcus905 ha scritto:
già era
refuso, scusate!


mah... non mi convince comunque... dentro il for

Codice:
for(i=1;i<=n;i++)
      {
       
         j++;
         if(j==c+1){j=1;}
         if(tavolo[j]==0){i--;}
       
      }


la variabile con la quale iteri è i, ma poi hai un i-- ... non che sia vietato ma è strano, almeno... non è lì il refuso?
Top
Profilo Invia messaggio privato HomePage
Crono
Semidio
Semidio


Registrato: 24/03/05 14:12
Messaggi: 224
Residenza: Trieste

MessaggioInviato: 02 Feb 2007 17:32    Oggetto: Rispondi citando

Dopo aver aggiunto un = nella condizione dell'ultimo if e un & davanti alle variabili in scanf sebbene il programma fosse sintatticamente corretto il risultato che restituiva non era quello che mi aspettavo perciò ho riscritto il codice, stai attento che non sono molte le combinazioni di c e di n per le quali è possibile azzerare tutti i valori di tavolo tranne uno.
Non ero sicuro se il tavolo fosse sempre di 500 elementi o se il numero di elementi dovesse essere c+1, ho corretto il codice considerando valida la prima ipotesi ma se mi fossi sbagliato basta fare le opportune modifiche

Codice:

#include<stdio.h>
#include<stdlib.h>

void main() {

 int i, c, n, tavolo[501], elimina=0;
 for(i=0; i<501; i++) tavolo[i]=0;

 //ripete la richiesta di immissione delle variabili fino a quando
 //i valori immessi non hanno senso
 do {
  system("cls"); //pulisce lo schermo
  scanf("%d %d", &c, &n);
 } while(c<1 || c>500 || n<1);

 for(i=1; i<=c; i++) tavolo[i]++;

 //ripete il ciclo fino a quando c diventa 1
 for(;;) {
  elimina+=n;
  if(elimina>500) elimina-=500;
  tavolo[elimina]=0;
  if(c==1) break;
  c--;
 }

 system("cls"); //pulisce lo schermo
 for(i=1; i<501; i++) if(tavolo[i]) printf("Il vincitore e': %d\n", i);
 system("pause"); //aspetta la pressione di un tasto per terminare il programma
}
Top
Profilo Invia messaggio privato
marcus905
Mortale devoto
Mortale devoto


Registrato: 12/05/06 21:05
Messaggi: 13

MessaggioInviato: 03 Feb 2007 00:33    Oggetto: Rispondi citando

allora............. dopo numerose lavorazioni ho ottenuro un programma che va coi miei dati sperimentali ma non coi dati random di verifica.

in pratica devo risolvere questo problema, riporto il testo in versione semplificata:

Nicola va a mangiare una pizza con i suoi C-1 amici. Per ravvivare la serata il ristoratore, prima che loro si siedano ad un tavolo rotondo, decise di offrire la pizza ad uno del gruppo, scegliendolo così: si sceglie un numero casuale N,poi cominciando dal posto di Nicola si conta in senso antiorario finquando non si arriva alla N-esima persona che dovrà pagare la sua pizza, si prosegue dal successivo contando ancora N persone ed eliminando la N-esima (ovviamente saltando gli eliminati) finquando solo uno non rimane, che quindi non pagherà la pizza. Scrivere un programma che con N<=100 e C<=500 sappia dire chi è il vincitore dle gioco.

dati di verifica
C=9; N=5; Seq. Eliminati ={5,1,7,4,3,6,9,2}; Vincitore=8;

e questo e' il mio programma che ha 2 problemi coi dati di verifica:
1. la sequenza eliminati è corretta fino alla 4a iterazione e dopo va a cavoli suoi e ancora non ho capito il perchè;
2. nonostante la sequanza è errata il programma sputa fuori il numero giusto del vincitore.

se invece inserisco altri dati non azzecca in tutti i casi il numero del vincitore ma prende quello dell'ultimo eliminato in alcuni come vincitore

Codice:


#include <stdio.h>

main()
{

   int n,elim;
   long int i,j,c;
   int tavolo[501];

   scanf("%d %d", &c, &n);
   for(i=1;i<=c;i++)
   {
      printf("breakfill in %d\n", i);
      tavolo[i]=1;
   }
   j=1;
   do
   {
      printf("break1\n");
      for(i=1;i<n;i++)
      {
         printf("breakfor in %d and %d\n", j, i);
         j++;
         if(j==c+1){j=1;}
         if(tavolo[j]==0){i--;}
      }

      tavolo[j]=0;
      printf("DELETED %d\n",j);
      j++;
      if(j==c+1){j=1;}
      elim=c;
      for(i=1;i<=c;i++)
      {
      
         if(tavolo[i]==1){elim--;}
      
      }
   }
   while(elim!=c-1);
   
   int vincitore;
   
   for(i=1;i<=c;i++)
   {
      printf("breakid in %d\n", i);
      if(tavolo[i]==1){vincitore=i;}
         
   }
   
   printf("%d\n", vincitore);
}




ignorate dove ho scritto break*, li ho messi per capire cosa faceva il programma in quel momento e vedere dove sballava... e da quanto ho compreso salta qualcosa attorno al decremento di i nel for relativo all'if di tavolo[j]==0 ma non ho capito dove sbaglio programmaticamente
Top
Profilo Invia messaggio privato
Crono
Semidio
Semidio


Registrato: 24/03/05 14:12
Messaggi: 224
Residenza: Trieste

MessaggioInviato: 04 Feb 2007 18:04    Oggetto: Rispondi citando

Questo codice dovrebbe essere corretto, prova a compilarlo e a fare delle prove

Codice:

#include <stdio.h>
#include<stdlib.h>

void main() {
 int i, j, c, n, elim=0, tavolo[500];

 //c deve essere compreso fra 2 e 500
 //n deve essere compreso fra 1 e 100
 //n non può essere pari altrimenti non resterà mai un solo vincitore
 do {
  system("cls"); //pulisce lo schermo
  printf("Introduci il numero di giocatori e un numero casuale\n");
  scanf("%d %d", &c, &n); //acquisisci le variabili
 } while(c<2 || c>500 || n<1 || n>100 || (n%2==0));

 for(i=0; i<c; i++) tavolo[i]=1; //inizializza i valori di tavolo necessari
 j=c; //inizializza j

 //fino a quando j è diverso da 1 ripeti il ciclo
 do {
  elim+=n; //formula equivalente a elim=elim+n;
  while(elim>=c) elim-=c; //se elim è superiore a c continua a decrementare elim di c
  tavolo[elim-1]=0; //elimina il giocatore
  j--;
 } while(j!=1);

 system("cls");
 for(i=0; i<c; i++) if(tavolo[i]) printf("Signore e signori il vincitore e' il numero %d\n", i); //mostra il posto del vincitore
 system("pause");
}
Top
Profilo Invia messaggio privato
marcus905
Mortale devoto
Mortale devoto


Registrato: 12/05/06 21:05
Messaggi: 13

MessaggioInviato: 04 Feb 2007 20:20    Oggetto: Rispondi citando

dopo numerose modifiche e aggiustamenitho risolto così

Codice:


#include <stdio.h>

main()
{

   int n,elim;
   long int i,j,c;
   int tavolo[501];

   scanf("%d %d", &c, &n);
   for(i=1;i<=c;i++)
   {
      //printf("breakfill in %d\n", i);
      tavolo[i]=1;
   }
   j=0;
   do
   {
      //printf("break1\n");
           i=1;
      do
      {
                  j++;
         if(j==c+1){j=1;}
                  if(tavolo[j]!=0){i++;}       
         //printf("breakw2 in %d and %d\n", j, i);
                  //printf("tavolo[%d] %d\n", j, tavolo[j]);
      }
           while(i<n+1);

      tavolo[j]=0;
      // printf("DELETED %d\n",j);
      elim=c;
      for(i=1;i<=c;i++)
      {
      
         if(tavolo[i]==1){elim--;}
      
      }
   }
   while(elim!=c-1);
   
   int vincitore;
   
   for(i=1;i<=c;i++)
   {
      //printf("breakid in %d\n", i);
      if(tavolo[i]==1){vincitore=i;}
         
   }
   
   printf("%d\n", vincitore);
   
}



e sembra funzionare... i commenti non sono altro che le righe di debug del programma precedente

grazie comunque a tutti quelli che mi hanno aiutato!

PS: non ho implementato i controlli sull'input perche' e' codice sperimentale.. poi lo faro' in seguito!
Top
Profilo Invia messaggio privato
Crono
Semidio
Semidio


Registrato: 24/03/05 14:12
Messaggi: 224
Residenza: Trieste

MessaggioInviato: 05 Feb 2007 09:42    Oggetto: Rispondi

Ieri pensavo di aver risolto il problema ma solo più tardi mi sono accorto di aver trascurato una delle specifiche del programma e di essermi dimenticato di aggiungere una cosa per cui ti ho dato un codice pesantemente sbagliato, quello che avrei dovuto darti è questo:

Codice:
#include<stdio.h>
#include<stdlib.h>

void main() {
 //i e j sono delle variabili contatore utilizzate dai cicli for
 //elim è un ulteriore variabile contatore utilizzata come indice di tavolo
 //c è il numero di giocatori e deve essere compreso tra 2 e 500
 //n è un numero che deve essere compreso tra 1 e 100
 //tavolo[500] serve a simulare il tavolo di giocatori
 int i, j, c, n, elim=0, tavolo[500];
 
 //la richiesta di inserimento di c ed n viene ripetuta fino a
 //quando i valori inseriti non sono conformi alle specifiche
 //del programma
 do {
  system("cls"); //pulisce lo schermo
  printf("Introduci il numero di giocatori e un numero a caso\n");
  scanf("%d %d", &c, &n); //acquisisce le variabili
 } while(c<2 || n<1 || c>500 || n>100); //condizioni di controllo del ciclo

 for(i=0; i<c; i++) tavolo[i]=1; //inizializza i valori di tavolo necessari
 
 //inizializza i con il valore di c e poi decrementalo di uno
 //ad ogni iterazione del ciclo fino a quando il valore di i
 //è diverso da 0
 for(i=c; i; i--) {
  //conta da 0 a n-1
  for(j=0; j<n; j++) {
   elim++; //incrementa elim di 1
   if(elim>c) elim=1; //se elim è maggiore di c elim diventa 1
   //fino a quando tavolo[elim-1] è 0 incrementa di uno elim
   while(!tavolo[elim-1]) {
    elim++;
    if(elim>c) elim=1;
   }
  }
  tavolo[elim-1]=0; //azzera il contenuto di uno dei valori di tavolo
 }

 system("cls"); //pulisce lo schermo
 printf("Il vincitore e' il numero %d\n", elim); //Visualizza il vincitore
 system("pause"); //premi di un tasto per terminare il programma
}
Top
Profilo Invia messaggio privato
Mostra prima i messaggi di:   
Nuovo argomento   Rispondi    Indice del forum -> Programmazione Tutti i fusi orari sono GMT + 1 ora
Pagina 1 di 1

 
Vai a:  
Non puoi inserire nuovi argomenti
Non puoi rispondere a nessun argomento
Non puoi modificare i tuoi messaggi
Non puoi cancellare i tuoi messaggi
Non puoi votare nei sondaggi