PDA

View Full Version : [C] Generare lettere casuali in array


Vincenzoflaminio
23-02-2010, 23:17
Salve ho bisogno di sviluppare queste due parti di programma :
Ad ogni giocatore
viene assegnato un numero casuale nell’intervallo [0,10]. In maniera casuale vengono
create 8 squadre.

struct _giocatore
{
char cognome;
char nome;
int valore;
}
typedef struct _giocatore Giocatore;

Giocatore array_giocatori[88]; */definisco un array di tipo GIOCATORE da 88
for (i=0;i<88;i++)
{
array_giocatori[i].valore=rand()%11 */ assegno un numero casuale da 1a10 }

Adesso dovrei fare lo stesso con i nomi e i cognomi :
Inizialmente vengono considerati 88 giocatori identificati dal Cognome e Nome (anche solo lettere casuali).

si puo fare cosi ?? :
struct _giocatore
{
char cognome;
char nome;
int valore;
}
typedef struct _giocatore Giocatore;

Giocatore array_giocatori[88]; */definisco un array di tipo GIOCATORE da 88
char nomi[21]={a,b,c,d,e,f,g,h,i,l,m,n,o,p,q,r,s,t,u,v,z};
char cognomi[21]={a,b,c,d,e,f,g,h,i,l,m,n,o,p,q,r,s,t,u,v,z};
for (i=0;i<88;i++)
{
array_giocatori[i].nome=rand()%nomi
array_giocatori[i].cognome=rand()%cognomi

WarDuck
23-02-2010, 23:23
Al volo:

se devi usare lettere (char), sappi che di fatto sono interi (compresi tra 65 e 90 per le lettere minuscole e maiuscole), per cui potresti fare in modo di estrarre un numero in quell'intervallo.

Dai un'occhiata alla tavola ASCII.

cionci
24-02-2010, 08:46
rand()%11 genera numeri da 0 a 10.

bobbytre
24-02-2010, 19:38
secondo me per i nomi e i cognomi ti conviene creare due array che contengano una 50ina di nomi propri di persona ( reali) e lo stesso per i cognomi
e poi in modo casuale li accoppi.
Se scegli le lettere in modo casuale ti escono nomi come djaskljdklas julktyujlkt che neppure nel villaggio piu sperduto della turchia riesci a trovare :)

Vincenzoflaminio
25-02-2010, 02:07
Al volo:

se devi usare lettere (char), sappi che di fatto sono interi (compresi tra 65 e 90 per le lettere minuscole e maiuscole), per cui potresti fare in modo di estrarre un numero in quell'intervallo.

Dai un'occhiata alla tavola ASCII.

Giusto!
se faccio cosi non posso scegliere la lunghezza del nome:

Giocatore array_giocatori[88];
for (i=0;i<88;i++)
{
array_giocatori[i].valore=(65+rand()%26);


potrei farlo cosi?? (non so se è giusto)



void rand_name (*char array_giocatore.nome, int lunghezza_nome)
{
int i;
char *pnome=array_giocatori.nome;
for (i=0;i<lunghezza_nome;i++)
{
*pnome++=(65+rand()%26);
} }

WarDuck
25-02-2010, 11:00
Non ho ben capito se vuoi generare nomi e cognomi come sequenze di lettere casuali oppure usare una singola lettera...

Nel primo caso secondo me ti conviene fare come ha detto bobbytre, ti crei due array di nomi e cognomi e poi li mischi casualmente (estrai un indice per i nomi, ed un indice per i cognomi).

Nel secondo caso è abbastanza semplice perché:


struct _giocatore
{
char cognome;
char nome;
int valore;
}
typedef struct _giocatore Giocatore;

Giocatore array_giocatori[88]; */definisco un array di tipo GIOCATORE da 88
for (i=0;i<88;i++)
{
array_giocatori[i].valore=rand()%11 */ assegno un numero casuale da 1a10

array_giocatori[i].nome = 65+rand()%26;
array_giocatori[i].cognome = 65+rand()%26;
}


Cmq se non vado errato prima di usare rand() dovresti inizializzare il seme con srand(..).

La struct che hai dichiarato contiene dei char, quindi singoli caratteri, non stringhe.

Rsk
25-02-2010, 11:09
Al volo:

se devi usare lettere (char), sappi che di fatto sono interi (compresi tra 65 e 90 per le lettere minuscole e maiuscole), per cui potresti fare in modo di estrarre un numero in quell'intervallo.

Dai un'occhiata alla tavola ASCII.
Non è necessario consultare la tavola ascii.
Si può tranquillamente fare
int main()
{
srand(time(NULL));
printf("%c ",'A'+rand()%('Z'-'A'));
return 0;
}

WarDuck
25-02-2010, 11:40
Non è necessario consultare la tavola ascii.
Si può tranquillamente fare
int main()
{
srand(time(NULL));
printf("%c ",'A'+rand()%('Z'-'A'));
return 0;
}


Si esatto si può fare benissimo così, anche se lascerei modulo 26...

bobbytre
25-02-2010, 15:38
una funzione random che si autoinzializza no ?


int random(int max)
{
static int init = 0;
if (!init)
{
init = 1;
srand(time(0));
}
return rand() % max;
}

Vincenzoflaminio
25-02-2010, 21:17
struct _giocatore
{
char cognome;
char nome;
int valore;
}
typedef struct _giocatore Giocatore;

Giocatore array_giocatori[88]; */definisco un array di tipo GIOCATORE da 88
for (i=0;i<88;i++)
{
array_giocatori[i].valore=rand()%11 */ assegno un numero casuale da 1a10

array_giocatori[i].nome = 65+rand()%26;
array_giocatori[i].cognome = 65+rand()%26;
}


Cmq se non vado errato prima di usare rand() dovresti inizializzare il seme con srand(..).

La struct che hai dichiarato contiene dei char, quindi singoli caratteri, non stringhe.

Va benissimo anche lettere casuali, l'esercizio cosi mi chiede:
Si supponga di gestire un torneo di calcio tra 8 squadre. Inizialmente vengono
considerati 88 giocatori identificati dal Cognome e Nome (anche solo lettere casuali). Ad ogni giocatore viene assegnato un numero casuale nell’intervallo [0,10]. In maniera casuale vengono create 8 squadre.

Ti volevo chiedere quindi come devo sostituire il char nome e il char cognome nella struct per renderle stringhe? il resto è giusto?

bobbytre
25-02-2010, 21:36
struct _giocatore
{
char *cognome;
char *nome;
int valore;
}




array_giocatori[i].nome = calloc(17,sizeof(char));
array_giocatori[i].cognome= calloc(17,sizeof(char));

for(int j=0;j<16;j++)
{
array_giocatori[i].nome[j] = 65+rand()%26;
array_giocatori[i].cognome[j] = 65+rand()%26;

}

Vincenzoflaminio
25-02-2010, 22:40
struct _giocatore
{
char *cognome;
char *nome;
int valore;
}




array_giocatori[i].nome = calloc(17,sizeof(char));
array_giocatori[i].cognome= calloc(17,sizeof(char));

for(int j=0;j<16;j++)
{
array_giocatori[i].nome[j] = 65+rand()%26;
array_giocatori[i].cognome[j] = 65+rand()%26;

}


Gentilissimo come sempre bobbytre :D
Allora hai usato due contatori "i" (per gli 88 giocatori) e "j" (per un nome da 16caratteri ) però non ho ben capito perchè usi un puntatore a una char , e il comando calloc cosa significa?

bobbytre
25-02-2010, 22:50
Gentilissimo come sempre bobbytre :D
Allora hai usato due contatori "i" (per gli 88 giocatori) e "j" (per un nome da 16caratteri ) però non ho ben capito perchè usi un puntatore a una char , e il comando calloc cosa significa?

calloc alloca dinamicamente la memoria e la inizializza a zero , ma forse ancora ti puo risultare complicato, non lo avevo calcolato :D

meglio cosi:

struct _giocatore
{
char cognome[17];
char nome[17];
int valore;
}

// ...

memset(array_giocatori[i].nome,0,sizeof(array_giocatori[i].nome));
memset(array_giocatori[i].cognome,0,sizeof(array_giocatori[i].cognome));

for(int j=0;j<16;j++)
{
array_giocatori[i].nome[j] = 65+rand()%26;
array_giocatori[i].cognome[j] = 65+rand()%26;

}

Vincenzoflaminio
01-03-2010, 20:01
struct _giocatore
{
char cognome[5];
char nome[5];
int valore;
}
typedef struct _giocatore Giocatore;

Giocatore array_giocatori[88]; */definisco un array di tipo GIOCATORE da 88
for (i=0;i<88;i++)
{
array_giocatori[i].valore=rand()%11 */ assegno un numero casuale (1-10)
int j=0;
for (j=0;j<5;j++);
array_giocatori[i].nome[j] = 65+rand()%26;
array_giocatori[i].cognome[j] = 65+rand()%26;

}


Cmq se non vado errato prima di usare rand() dovresti inizializzare il seme con srand(..).

La struct che hai dichiarato contiene dei char, quindi singoli caratteri, non stringhe.

Ho visto che le stringhe sono array di char 1D, quindi ho dichiarato char array da 5 nella struct. Cerco di avvicinarmi a questo codice perchè non voglio andare oltre quello che ho studiato. Bobbytre anche memset non lo conosco...
Ho provato ad usare due contatori in modo da definire quanti caratteri inserire che ne dite??

cionci
01-03-2010, 20:07
memset serve per azzerare il contenuto del vettore. Puoi farlo anche tu manualmente.

Vincenzoflaminio
01-03-2010, 20:18
memset serve per azzerare il contenuto del vettore. Puoi farlo anche tu manualmente.

Se aggiungiamo il memset per azzerare l'array, la parte di codice che ho postato sopra è giusta?

bobbytre
01-03-2010, 23:44
Se aggiungiamo il memset per azzerare l'array, la parte di codice che ho postato sopra è giusta?

no ! non è giusto il codice

questo:

array_giocatori[i].valore=rand()%11 */ assegno un numero casuale (1-10)

non fa quello che ti aspetti !

in questo:
for (i=0;i<88;i++)
{
array_giocatori[i].valore=rand()%11 */ assegno un numero casuale (1-10)
int j=0;
for (j=0;j<5;j++);
array_giocatori[i].nome[j] = 65+rand()%26;
array_giocatori[i].cognome[j] = 65+rand()%26;

}

il secondo for gira a vuoto e i nomi non vengono generati.

Vincenzoflaminio
02-03-2010, 15:22
no ! non è giusto il codice

questo:

array_giocatori[i].valore=rand()%11 */ assegno un numero casuale (1-10)

non fa quello che ti aspetti !



Ho appena provato in DEV c++
il codice genera correttamente valori casuali :

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

struct _giocatore
{
char cognome[5];
char nome[5];
int valore;
};
typedef struct _giocatore Giocatore;

void visualizza_aI (int v[], int n)
{
int i;
for (i=0;i<n;i++)
printf("%4d", v[i]);
}

int main()
{
srand((unsigned int)time(0));
Giocatore array_giocatori[88];
int i;
int j=0;
for (i=0;i<88;i++)
{
array_giocatori[i].valore=rand()%11;
while (j<5)
{
array_giocatori[i].nome[j] =rand()%26 + 65;
j++;
}
}

printf("visualizzo valore in giocatore [5] %d", array_giocatori[5].valore);
printf("visualizza i caratteri %c\n ",array_giocatori[3].nome[5]);
printf("visualizza i caratteri %c\n ", array_giocatori[3].nome[4]);



system("PAUSE");
return 0;
}


}
Ultima modifica ... sono riuscito a risolvere anche il problema della generazione delle lettere casuali con un while , l'unico stranezza e che se stampo dei caratteri a caso di un array mi escono anche caratteri come APICI " o lettere maiuscole