PDA

View Full Version : [C] Esercizio cifre ripetute (errore in esecuzione)


gioe
21-09-2011, 11:44
Ciao a tutti.
Sto facendo un esercizio sugli array dove in input viene inserito un numero e stabilisce se il numero contiene cifre ripetute ed in caso affermativo quali.
Compilando tutto ok, ma in esecuzione su alcuni numeri funziona bene su altri no. Esempio:
n = 58585858

Ci sono 2 cifre ripetute: 5 8

n = 5858585858

Ci sono 3 cifre ripetute 1 5 6 :eek:

io credo l'errore sia nel ciclo for ma non riesco a capire dove:

for(i--; i >= 0; i--){
for(j = i-1; j>=0; j--)
if( (numero[j] == numero[i]) && (numero[i] < 10) ){
numero[j] = 10; /*Per "eliminare" le cifre ripetute */
ripetuto = 1;
}

if(ripetuto){
cifre[cnt] = numero[i];
cnt++;
}

ripetuto = 0;

}

i prima del ciclo for contiene la lunghezza di numero e cnt contiene 0.
Spero di essermi spiegato bene e scommetto che il problema sarà dovuto ad una cavolata banale che non riesco a vedere :D. Comunque vi ringrazio in anticipo

ESSE-EFFE
21-09-2011, 13:32
Posta tutto il codice necessario a compilare.

gioe
21-09-2011, 13:55
Posta tutto il codice necessario a compilare.

Ecco


#include <stdio.h>
#define N 100

int main(void)
{
int d, cnt, i, j, ripetuto, numero[N];
cnt = 0;
ripetuto = 0;

printf("Inserisci un numero: ");
scanf("%d", &d);

/*inseriamo le cifre nell'array numero[N], l'array cifre sarà dichiarato dopo questo FOR
* per usare solo la memoria necessaria ed evitare sprechi */

for(i = 0; d != 0; i++){
numero[i] = d%10;
d /= 10;
}

int cifre[i/2]; /*caso peggiore*/

for(i--; i >= 0; i--){
for(j = i-1; j>=0; j--)
if((numero[j] == numero[i])&&(numero[i] < 10)){
numero[j] = 10; /*Per "eliminare" le cifre ripetute */
ripetuto = 1;
}

if(ripetuto){
cifre[cnt] = numero[i];
cnt++;
}

ripetuto = 0;
}


/*e così abbiamo svolto il programma.. ora stampiamo il tutto */
if(cnt>0){
printf("ci sono %d cifre ripetute: ", cnt);
for(i = 0; i < cnt; i++)
printf("%d ", cifre[i]);
}
else
printf("Non ci sono cifre ripetute!");

putchar('\n');
return 0;
}

GByTe87
21-09-2011, 13:59
Ehm...

int cifre[i/2]; /*caso peggiore*/

Non è il massimo fare una cosa del genere... se proprio vuoi dimensionare l'array in base al caso peggiore usa una malloc.

ESSE-EFFE
21-09-2011, 14:07
Ehm...

int cifre[i/2]; /*caso peggiore*/

Non è il massimo fare una cosa del genere... se proprio vuoi dimensionare l'array in base al caso peggiore usa una malloc.

Non capisco come possa compilargli una cosa simile...

GByTe87
21-09-2011, 14:10
Non capisco come possa compilargli una cosa simile...

Mmm, onestamente non so se i VLA (http://en.wikipedia.org/wiki/Variable-length_array) del C99 consentono una cosa del genere.. :confused:

ESSE-EFFE
21-09-2011, 14:12
printf("Inserisci un numero: ");
scanf("%d", &d);



Il numero in input viene letto come intero, quindi 5858585858 è troppo grande, non ci sta in 32 bit (suppongo tu stia usando un compilatore a 32 bit) e in d va a finire 1563618562. Ti bastavano 30 secondi di debug per vederlo. Se vuoi gestire numeri così grandi, ti consiglio di leggerli come stringa, tanto non ha senso fare la conversione, sempre caratteri ripetuti sono. In quel caso stai solo attento al controllo "numero[i] < 10".

ESSE-EFFE
21-09-2011, 14:14
Mmm, onestamente non so se i VLA (http://en.wikipedia.org/wiki/Variable-length_array) del C99 consentono una cosa del genere.. :confused:
Non so. A me non compilava, però le cifre sono 10 quindi il caso peggiore è semplicemente "int cifre[10];".

Floris
21-09-2011, 20:29
Forse ti conviene prendere il numero in input come una stringa.
In questo modo non hai limiti di grandezza sul numero inserito ed inoltre le operazioni che tu vuoi fare risultano più semplici.
Ti basterebbe ad esempio tenere un array ausiliario di 10 elementi e poi fare una cosa del genere:

...
char* numero = ... //dato in input
int n = ... //lunghezza della stringa che rappresenta il numero
int* aux = new int[10];
for(int i=0; i<10; i++)
aux[i]=0;
for(int i=0; i<n; i++)
aux[numero[i]]++;
//ora stampi i valori doppi
for(int i=0; i<10;i++){
if(aux(i)>1)
cout<<"numero "+i+" ripetuto "+aux[i]+" volte";
}
...

gioe
22-09-2011, 16:21
Il testo dell'esercizio richiedeva esplicitamente di usare scanf("%d", &n) quindi il limite dell'int è colpa dell'esercizio :D. Volevo ringraziarvi tutti quanti ed approfittare per chiedere una curiosità su quel "cifre[i/2]" a me non da nessun problema in compilazione nemmeno con -ansi, -pedantic, -Wall perché sarebbe sbagliato? non è l'equivalente di *(cifre + i/2)? Sto cercando di imparare :D

Grazie ancora

GByTe87
22-09-2011, 16:32
Il testo dell'esercizio richiedeva esplicitamente di usare scanf("%d", &n) quindi il limite dell'int è colpa dell'esercizio :D.

Se sei costretto ad usare scanf("%d", &n) allora devi acquisire il numero cifra per cifra, non tutto insieme. :)

Volevo ringraziarvi tutti quanti ed approfittare per chiedere una curiosità su quel "cifre[i/2]" a me non da nessun problema in compilazione nemmeno con -ansi, -pedantic, -Wall perché sarebbe sbagliato? non è l'equivalente di *(cifre + i/2)? Sto cercando di imparare :D

Mmm, quando si definiscono degli array in modo statico la loro dimensione deve essere nota a compile-time; nel caso in questione non lo è perchè il valore di i può variare da esecuzione ad esecuzione.
Probabilmente, come ho detto prima, i VLA introdotti col C99 permettono questo, ma in casi del genere (cioè quando la dimensione non è nota durante la scrittura del codice) personalmente preferisco ricorrere all'allocazione dinamica. :D