Se avete dubbi o domande sulla programmazione in generale, fatele qui

Messaggio12 settembre 2009, 12:30 - C: eliminare doppioni generati da rand #44966

Ciao a tutti e buona giornata :) Volevo provare ad implementare un modo per eliminare i numeri doppi, solo che non ho idee. Il mio programma estrae i numeri del SuperEnalotto quindi se per caso un numero appare due volte non va bene :( Qualcuno sa come fare? vi allego il sorgente. Grazie di cuore :D

Codice: Seleziona tutto
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main() {

  // i = variabile per ciclo for
  // n = variabile per ciclo for
  // c = variabile per il numero SuperStar
  // v = vettore per bubble sort
  int i, n, c = 0, v[6];
 
  // q = variabile per la domanda
  char q;

  int bubbleSort(int numbers[], int array_size);

  // insemina rand
  srand(time(NULL));
 
  printf("Vuoi giocare il numero SuperStar? <S/n> ");
  scanf("%c", &q);

  // diminuisce c in modo che non venga stampato il numero SuperStar
  if (q == 'n' || q == 'N') {
    --c;
    printf("Schedina SuperEnalottonGiocata 01 | Giocata 02n");
  }
 
  else
    printf("Schedina SuperEnalottonGiocata 01 | Giocata 02 | Numero SuperStarn");

  // ciclo per le 2 estrazioni
  for (i = 0; i < 2; ++i) {

  // assegna i 6 numeri al vettore
  for (n = 0; n < 6; ++n)
    v[n] = rand() % 90 + 1;
 
  // ordina il vettore
  bubbleSort(v, 6);

  // stampa a video il vettore
  for (n = 0; n < 6; ++n)
    printf("%d ", v[n]);

  printf("n");
  ++c;
 
  // stampa a video il numero SuperStar
  if (c == 2)
    printf("%dn", v[0] = rand() % 90 + 1);
 
  }
 
  return 0;
}

// funzione bubbleSort
int bubbleSort(int numbers[], int array_size)
{
  int i, j, temp;

  for (i = (array_size - 1); i > 0; i--)
  {
    for (j = 1; j <= i; j++)
    {
      if (numbers[j-1] > numbers[j])
      {
        temp = numbers[j-1];
        numbers[j-1] = numbers[j];
        numbers[j] = temp;
      }
    }
  }
  return 0;
}
Ultima modifica di simo91 il 12 settembre 2009, 13:03, modificato 1 volta in totale.
Arch Linux i686
Jabber, per chiunque: simo91@jabber.org - My blog
simo91
Arciere
 
Messaggi: 237
Iscritto il: 24 agosto 2008, 12:53
Località: Bologna
Top

Messaggio12 settembre 2009, 13:03 - C: eliminare doppioni generati da rand #44969

usa un algoritmo di ricerca per controllare se il numero e' gia' nell'array.. se lo e', ripeti l'estrazione..
;) ;)
issproevolution
Arciere Provetto
 
Messaggi: 517
Iscritto il: 22 settembre 2007, 20:20
Località: /dev/null
Top

Messaggio12 settembre 2009, 13:25 - C: eliminare doppioni generati da rand #44976

issproevolution ha scritto:usa un algoritmo di ricerca per controllare se il numero e' gia' nell'array.. se lo e', ripeti l'estrazione..
;) ;)

praticamente una specie di bubble sort con il confronto dei numeri :) giusto?
Arch Linux i686
Jabber, per chiunque: simo91@jabber.org - My blog
simo91
Arciere
 
Messaggi: 237
Iscritto il: 24 agosto 2008, 12:53
Località: Bologna
Top

Messaggio12 settembre 2009, 13:46 - C: eliminare doppioni generati da rand #44984

simo91 ha scritto:
issproevolution ha scritto:usa un algoritmo di ricerca per controllare se il numero e' gia' nell'array.. se lo e', ripeti l'estrazione..
;) ;)

praticamente una specie di bubble sort con il confronto dei numeri :) giusto?

No. Molto più semplice: passi in rassegna l'array con un semplice ciclo for e confronti il numero appena estratto con ogni numero contenuto nell'array.
Se l'array è di grosse dimensioni (ma mi pare di capire non sia il tuo caso) ed è già ordinato puoi invece usare un algoritmo di ricerca binaria che si basa semplicemente sul cosiddetto "teorema degli zeri".
Howl
Arciere Provetto
 
Messaggi: 435
Iscritto il: 28 luglio 2008, 19:32
Top

Messaggio14 settembre 2009, 10:27 - C: eliminare doppioni generati da rand #45149

Ho aggiunto queste poche righe e così dovrebbe andare bene:

Codice: Seleziona tutto
  // rileva doppioni
  for (n = 1; n < 6; ++n) {
    if (v[n] == v[n - 1])
      goto error;
  }

queste subito dopo l'ordinamento del vettore e subito prima che i numeri vengano stampati a schermo, poi ho messo
Codice: Seleziona tutto
error:

prima dell'inizio dei due cicli per le estrazioni. So che non viene consigliato l'uso di goto però in questo caso mi sembrava la soluzione più semplice e pulita, altre idee sono sempre ben accette :) grazie mille !!
Arch Linux i686
Jabber, per chiunque: simo91@jabber.org - My blog
simo91
Arciere
 
Messaggi: 237
Iscritto il: 24 agosto 2008, 12:53
Località: Bologna
Top

Messaggio14 settembre 2009, 11:21 - C: eliminare doppioni generati da rand #45165

Ho dovuto modificare un pò il programma perchè dopo l'inserimento di quelle righe nascevano altri problemi, ora dovrebbe essere tutto ok, vi lascio il sorgente nel caso vi possa servire, saluti.

Codice: Seleziona tutto
// superenalotto.c 14/09/2009

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

int main() {

  // n = variabile per i cicli for
  // c = variabile per il numero SuperStar
  // v = vettore per la prima estrazione
  // z = vettore per la seconda estrazione
  int n, c = 1, v[6], z[6];
 
  // q = variabile per la domanda
  char q;

  int bubbleSort(int numbers[], int array_size);

  // insemina rand
  srand(time(NULL));
 
  printf("Vuoi giocare il numero SuperStar? <S/n> ");
  scanf("%c", &q);

  // diminuisce c in modo che non venga stampato il numero SuperStar
  if (q == 'n' || q == 'N') {
    --c;
    printf("Schedina SuperEnalottonGiocata 01 | Giocata 02n");
  }
 
  else
    printf("Schedina SuperEnalottonGiocata 01 | Giocata 02 | Numero SuperStarn");
 
  // ripete le estrazioni se vengono trovati doppioni
  error:

  // assegna i 6 numeri al vettore v
  for (n = 0; n < 6; ++n)
    v[n] = rand() % 90 + 1;
 
  // ordina il vettore v
  bubbleSort(v, 6);

  // rileva doppioni nel vettore v
  for (n = 1; n < 6; ++n) {
    if (v[n] == v[n - 1])
      goto error;
  }

  // assegna i 6 numeri al vettore z
  for (n = 0; n < 6; ++n)
    z[n] = rand() % 90 + 1;

  // ordina il vettore z
  bubbleSort(z, 6);

  // rileva doppioni nel vettore z
  for (n = 1; n < 6; ++n) {
    if (z[n] == z[n - 1])
      goto error;
  }

  // stampa a video il vettore v
  for (n = 0; n < 6; ++n)
    printf("%d ", v[n]);

  printf("n");

  // stampa a video il vettore z
  for (n = 0; n < 6; ++n)
    printf("%d ", z[n]);

  printf("n");
 
  // stampa a video il numero SuperStar
  if (c == 1)
    printf("%dn", v[0] = rand() % 90 + 1);
 
  return 0;
}

// funzione bubbleSort
int bubbleSort(int numbers[], int array_size) {
 
  int i, j, temp;

  for (i = (array_size - 1); i > 0; i--) {
    for (j = 1; j <= i; j++) {
      if (numbers[j - 1] > numbers[j]) {
        temp = numbers[j - 1];
        numbers[j - 1] = numbers[j];
        numbers[j] = temp;
      }
    }
  }
  return 0;
}
Ultima modifica di simo91 il 14 settembre 2009, 11:22, modificato 1 volta in totale.
Arch Linux i686
Jabber, per chiunque: simo91@jabber.org - My blog
simo91
Arciere
 
Messaggi: 237
Iscritto il: 24 agosto 2008, 12:53
Località: Bologna
Top

Messaggio14 settembre 2009, 19:27 - C: eliminare doppioni generati da rand #45256

O_O Paura...

Il programma sopra è un monumento all'inefficienza... Puoi fare molto di meglio... E ti prego, disimpara i GoTo, sono peggio della peste o della AH1N1...
- In development -
Cif
Novello Arciere
 
Messaggi: 34
Iscritto il: 27 agosto 2007, 9:53
Località: Vicenza
Top

Messaggio14 settembre 2009, 19:34 - C: eliminare doppioni generati da rand #45259

Cif ha scritto:O_O Paura...

Il programma sopra è un monumento all'inefficienza... Puoi fare molto di meglio... E ti prego, disimpara i GoTo, sono peggio della peste o della AH1N1...

Bhè a me interessa che il programma funzioni, e meglio di così non so fare. Il goto è comodissimo messo lì :D Se hai idee migliori aiutami pure..
Arch Linux i686
Jabber, per chiunque: simo91@jabber.org - My blog
simo91
Arciere
 
Messaggi: 237
Iscritto il: 24 agosto 2008, 12:53
Località: Bologna
Top

Messaggio14 settembre 2009, 19:48 - C: eliminare doppioni generati da rand #45262

ma scusami scusami scusami...
quanti numeri sono? 90? allora crea un array di 90 posizioni e metti uno sul numero che è uscito e 0 negli altri.. per controllare se un numero N è uscito fai USCITI[N]!=1
Slackware -> Gentoo -> Archlinux
http://lanziani.com/blog/
Nss
Novello Arciere
 
Messaggi: 50
Iscritto il: 23 gennaio 2008, 11:20
Top

Messaggio14 settembre 2009, 22:25 - C: eliminare doppioni generati da rand #45272

quoto la soluzione di nss, quando devi lavorare su un numero finito basso di valori il counting è l'approccio migliore ;)

anche il goto si può sostituire con un while o equivalente . .

ecco una soluzione alternativa (fatta in 5min quindi non necessariamente corretta;)
Codice: Seleziona tutto
// superenalotto.c 14/09/2009

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

int main() {

  // n = variabile per i cicli for
  // c = variabile per il numero SuperStar
  // v = vettore per la prima estrazione
  // z = vettore per la seconda estrazione
  int n, c = 1, v[6], z[6];
 
  // q = variabile per la domanda
  char q;

  int numeri_gia_usciti[91];
 

  // insemina rand
  srand(time(NULL));
 
  printf("Vuoi giocare il numero SuperStar? <S/n> ");
  scanf("%c", &q);

  // diminuisce c in modo che non venga stampato il numero SuperStar
  if (q == 'n' || q == 'N') {
    --c;
    printf("Schedina SuperEnalottonGiocata 01 | Giocata 02n");
  }
 
  else
    printf("Schedina SuperEnalottonGiocata 01 | Giocata 02 | Numero SuperStarn");
 
   for(n=1;n<=90;n++)
    numeri_gia_usciti[n]=0;
   for (n = 0; n < 6; ++n){
    do{   
        v[n] = rand() % 90 + 1;
   }while(numeri_gia_usciti[v[n]]);
   numeri_gia_usciti[v[n]]=1;
   }
 

  // assegna i 6 numeri al vettore z
  for(n=1;n<=90;n++)
   numeri_gia_usciti[n]=0;
  for (n = 0; n < 6; ++n){
    do{   
       z[n] = rand() % 90 + 1;
    }while(numeri_gia_usciti[z[n]]);
    numeri_gia_usciti[z[n]]=1;
   }

  // stampa a video il vettore v
  for (n = 0; n < 6; ++n)
    printf("%d ", v[n]);

  printf("n");

  // stampa a video il vettore z
  for (n = 0; n < 6; ++n)
    printf("%d ", z[n]);

  printf("n");
 
  // stampa a video il numero SuperStar
  if (c == 1)
    printf("%dn", v[0] = rand() % 90 + 1);
 
  return 0;
}

ps:il bubblesort è abbastanza scarso come algoritmo . . se proprio devi, usa un merge (o una funzione sort nativa da libreria ;) )
ImmagineOutside of a dog, computers are a man's best friend, inside a dog it's too dark to type.
aleph
Robin Hood
 
Messaggi: 1530
Iscritto il: 12 febbraio 2008, 17:30
Top

Messaggio15 settembre 2009, 10:50 - C: eliminare doppioni generati da rand #45293

aleph ha scritto:quoto la soluzione di nss, quando devi lavorare su un numero finito basso di valori il counting è l'approccio migliore ;)

Ma stiamo parlando di 6 numeri! Forse è la soluzione più elegante, però non è che si guadagni molto in efficienza (anche perché devi inizializzare un array di 90 numeri, ma sopratutto perché con valori di n così bassi dovremmo confrontare il tempo di esecuzione di ogni operazione per guadagnare alla fine 1 ciclo di clock se ci va bene ).

ps:il bubblesort è abbastanza scarso come algoritmo . . se proprio devi, usa un merge (o una funzione sort nativa da libreria ;) )

Ripeto: stiamo parlando di 6 numeri! Usare il merge sort, che tra l'altro non è poi così intuitivo come il bubble sort, è totalmente controproducente. Piuttosto usa il selection sort che per valori di n bassi è molto efficiente e sicuramente più intuitivo del merge.

Sul goto: sono d'accordo che qui poteva essere evitato, ma comunque non cerchiamo di imparare quello che ci hanno insegnato a scuola come un dogma: il goto rimane ancora l'unico modo per implementare un decente (anche se forse un po' "triviale") meccanismo di gestione degli errori in C.
Howl
Arciere Provetto
 
Messaggi: 435
Iscritto il: 28 luglio 2008, 19:32
Top

Messaggio15 settembre 2009, 14:35 - C: eliminare doppioni generati da rand #45309

è una questione di approcci . . io preferisco sempre usare algoritmi per quanto possibile scalabili, di modo che se devo modificare il programma non ho problemi . . il select forse è un pò esagerato (dipende quanto il compilatore può ottimizzare l'azzeramento), però genera del codice più compatto e sicuramente più scalabile . . per dire si poteva anche tenere un vettore dei numeri usciti e fare il controllo su di quello, in questo caso sarebbe più efficiente . . . questione di gusti :P . .

per il goto: io preferisco evitarlo se posso . . gli errori recuperabili preferisco gestirli con un while, quelli irrecuperabili con un error() o un return ERROR_CODE . . . anche qui sono gusti :P . .

esempio più efficiente
Codice: Seleziona tutto
     int numeri_gia_usciti[6],i;
   for (n = 0; n < 6; ++n){
    loop:
    v[n] = rand() % 90 + 1;
      for(i=0;i<n;i++)
         if(numenumeri_gia_usciti[i]==v[n])
            goto loop;
   numeri_gia_usciti[n]=v[n];
   }

e qua invece un goto lo uso perchè in c manca un costrutto break N o continue N per spezzare più livelli di cicli (odio il c che mi costringe a usare i goto :mad: , invero volendo si potrebbe usare una flag, ma odio le flag più ancora dei goto :P . . )
ImmagineOutside of a dog, computers are a man's best friend, inside a dog it's too dark to type.
aleph
Robin Hood
 
Messaggi: 1530
Iscritto il: 12 febbraio 2008, 17:30
Top

Messaggio15 settembre 2009, 21:57 - C: eliminare doppioni generati da rand #45331

aleph ha scritto:e qua invece un goto lo uso perchè in c manca un costrutto break N o continue N per spezzare più livelli di cicli (odio il c che mi costringe a usare i goto :mad: , invero volendo si potrebbe usare una flag, ma odio le flag più ancora dei goto :P . . )

Si può evitare lo stesso, usando dei DO ... WHILE e WHILE con delle condizioni differenti per incrementare le variabili.
- In development -
Cif
Novello Arciere
 
Messaggi: 34
Iscritto il: 27 agosto 2007, 9:53
Località: Vicenza
Top

Messaggio16 settembre 2009, 11:23 - C: eliminare doppioni generati da rand #45354

fgr
Arciere
 
Messaggi: 188
Iscritto il: 2 dicembre 2008, 19:31
Top


Torna a Programmazione

Chi c’è in linea

Visitano il forum: Nessuno e 0 ospiti

Moderatori: 4javier, aleph, veleno77, adriano, Hilinus