View Full Version : [C] Divisibilità per 11
Ciao :)
Sono di fronte a questo problema:
Scrivere un programma C ricorsivo che dica se un numero n è divisibile per 11.
Io ho provato a farlo così:
#include <stdio.h>
#include <math.h>
int div_per11(int);
int sp(int);
int sd(int);
int main(void){
int num;
printf("Inserisci numero: ");
scanf("%d", &num);
if(div_per11(num))
printf("Il numero è divisibile per 11");
else
printf("Il numero non è divisibile per 11");
return 0;
}
int sp(int n){
if (n>0)
return (n%10)+sp(n/100);
else return 0;
}
int sd(int n){
n/=10;
if (n>0)
return (n%10)+sd(n/100);
else return 0;
}
int div_per11(int n){
if(n%11)
return 1;
else return (div_per11(abs(sp(n)-sd(n))));
}
Il problema è che prima di tutto non me lo compila perché dice che abs non è definito da nessuna parte (non uso Linux, uso Codeblocks per Windows) e poi volevo sapere se avevo fatto bene la parte ricorsiva. Grazie :)
if((numero % 11) == 0)
//divisibile
else
//non divisibile
il resto che c'entra :mbe: a che serve la ricorsione?
non so assolutamente niente di C. cmq a livello di algoritmo non capisco a cosa serva tutto quel papiro di codice...
L'algoritmo per vedere se un numero è divisibile per 11 o no è il seguente:
Dato un numero n si dice sp(n) e sd(n) rispettivamente la somma delle cifre pari e delle cifre dispari in n. Se la differenza in valore assoluto tra sp(n) e sd(n) è divisibile per 11 allora vuol dire che n è divisibile per 11.
Ecco devo implementare questo algoritmo in C. :)
Beh, o usi l'algoritmo o usi l'operatore %, altrimenti non ha senso l'algoritmo usato per vedere se il numero è divisibile per 11, quando già sai che non lo è facendo "numero%11", :)
EDIT: ma poi scusa, prendiamo 121 (11 *11), pari: 2 dispari:1+1=2 viene 0 / 11 :oink: Sei sicuro della formula?
ma poi scusa, prendiamo 121 (11 *11), pari: 2 dispari:1+1=2 viene 0 / 11 Sei sicuro della formula?
Sono sicuro ;)
http://www.math.it/formulario/divisibilita.htm
0 è divisibile per qualsiasi numero tranne che per se stesso.
Beh, o usi l'algoritmo o usi l'operatore %, altrimenti non ha senso l'algoritmo usato per vedere se il numero è divisibile per 11, quando già sai che non lo è facendo "numero%11",
Infatti ho aperto il thread apposta per sapere come implementarlo dato che il mio sicuramente ha qualcosa che non va. Devo farlo in maniera ricorsiva.
Poi non capisco perché il compilatore mi dice che abs non è dichiarata da nessuna parte :confused:
fuocofatuo
07-11-2005, 17:35
Certo che questo codice non ha alcuna utilità pratica... è decine di volte peggiore del semplice n%11==0 ...
Ma tant'è: te l'han chiesto ricorsivo, perciò volevano propio questo...
Mi hanno chiesto di implementare questo algoritmo perché mi hanno dato degli esercizi sulla ricorsione, deve essere utile solamente per farmi capire bene la ricorsione tutto qui :)
Mi hanno chiesto di implementare questo algoritmo perché mi hanno dato degli esercizi sulla ricorsione, deve essere utile solamente per farmi capire bene la ricorsione tutto qui :) avrebbero potuto darti miliardi di esercizi migliori e di grande utilità pratica... -.-'
comunque ci riporti esattamente gli errori del compilatore con anche i numeri di linea?
L'errore è esattamente in questa linea:
else return (div_per11(abs(sp(n)-sd(n))));
e mi dice che abs non è dichiarata in alcun punto.
L'errore è esattamente in questa linea:
else return (div_per11(abs(sp(n)-sd(n))));
e mi dice che abs non è dichiarata in alcun punto. prova ad includere <stdlib.h> come prima libreria, e se non va prova "_abs" anziché "abs".
Grazie con stdlib.h me lo compila.... però non sono sicuro che funzioni correttamente. Troppe volte mettendo numeri a caso mi dice che il numero è divisibile per 11. :(
EDIT...
il codice ha ben poco senso...
la funzione div_per11 così com'è non va bene, devi usare l'algoritmo che hai citato e poi usi il MOD? :mbe:
In teoria per numeri di mooooolte cifre dovrebbe essere più veloce la funzione ricorsiva che %11.
Comunque non dovresti utilizzare %11, ma ricorrere finchè trovi un numero <11: se è diverso da zero il numero non è divisibile per 11.
(PS non so se questo è il posto più adatto per i compiti per casa... :D )
Cioè quindi dovrei cambiare proprio il caso base? E dirgli che se un numero è minore di 11 controllo che sia anche uguale a 0 per dire che è divisibile?
Ho letto bene il tuo programma e non mi sembra che sia ricorsivo, ed è pure sbagliato.
Il codice:
if(n%11)
return 1;
ritorna 1 se il numero NON è divisibile per 11, e poi nel main
if(div_per11(num))
printf("Il numero è divisibile per 11");
dice che è divisibile per per 11 se div_per11 è divisibile per 11.
Credo (dovrei controllare) che dovrebbe essere dare i risultati corretti se fosse (nel main):
if(div_per11(num))
printf("Il numero non è divisibile per 11");
else
printf("Il numero è divisibile per 11");
return 0;
Comunque è ricorsivo per modo di dire, che fai il test sul numero che passa l'utente, e poi fai la ricorsione solo quando sai già che è divisibile per 11.
La funzione div_per11 dovrebbe
se il numero è minore di 11, riportare il risultato (0 o 1)
se è maggiore di 11, chiamare div_per11 con la differenza delle somme delle cifre di posto pari e dispari.
Non voglio essere più preciso perché altrimenti non imparesti nulla.
mega OT: r., la citazione che hai in firma è stupenda, ti stimo troppo!! :D :rotfl:
ps: riconosci la mia? :D
@71104: non non me la ricordavo, ma G.E.M.A. (google e' mio amico)
-> yattaman?
fuocofatuo
08-11-2005, 03:11
In teoria per numeri di mooooolte cifre dovrebbe essere più veloce la funzione ricorsiva che %11.
Credo proprio di no.
Il criterio di divisibilità citato è molto comodo per il calcolo manuale, perchè adoperando i numeri in base dieci è facile far la somma di cifre pari e dispari. Ma per un computer, che opera in base due, dividere per 10 è difficile quanto dividere per 11.
Sono sicuro ;)
http://www.math.it/formulario/divisibilita.htm
0 è divisibile per qualsiasi numero tranne che per se stesso.
Infatti ho aperto il thread apposta per sapere come implementarlo dato che il mio sicuramente ha qualcosa che non va. Devo farlo in maniera ricorsiva.
Poi non capisco perché il compilatore mi dice che abs non è dichiarata da nessuna parte :confused:
Ah, ecco, lì dice le cifre di posto pari e dispari, non le cifre pari e dispari :)
Grazie mille r. credo di aver capito ;)
Una cosa però.... nel main ho scritto
if(div_per11(num))
printf("E' divisibile");
perché non dovrebbe andare? Se io ritorno 1 dalla funzione (e quindi un valore diverso da 0) significa che è divisibile. Altrimenti se ritorno 0 non è divisibile.
Il programma ora funziona alla perfezione :D
@71104: non non me la ricordavo, ma G.E.M.A. (google e' mio amico)
-> yattaman? precisamente :D
scusate l'OT ragazzi, ora la piantiamo :p
leadergl
08-11-2005, 18:09
questa cosa mi piace un casino:
per 11
un numero è divisibile per 11 se la differenza (presa in valore assoluto), fra la somma delle cifre di posto pari e la somma delle cifre di posto dispari, è 0, 11 o un multiplo di 11
» per es. 625834 è divisibile per 11 in quanto (2+8+4)-(6+5+3)=14-14=0
cioè la parte "o un multiplo di 11" mi piace troppo...se mi esce "220" che è multiplo di 11 che cavolo di risultato ho trovato?!?! nessuno perchè il mio scopo è sapere se un numero è divisibile per 11 (di conseguenza è un suo multiplo...
cmq, e sicuramente non è la strada più ottimizzata, avrei fatto una cosa banalissima del tipo:
funzione Divisibile([passaggio per riferimento] NUMERO)
se NUMERO>=11 allora
Divisibile(NUMERO-11)
altrimenti
se (numero=0) allora
Divisibile=TRUE
fine se
fine se
vabbè questo è alla buona ma credo che alla fine faccia il suo lavoro...certo se poi mi metti che NUMERO=999999999999999999999 non la finiamo più e quindi il metodo delle cifre pari e dispari è decisamente più ottimizzato...
Allora, tre post in uno:
@fuocofatuo: Hai ragione. Il suddetto algoritmo va bene per il calcolo manuale. Però se si volessero testare numeri >MAX_INT (2^32-1), in teoria uno potrebbe farlo trattando il numero immesso come array di cifre, senza mai convertirlo in numero (non so se mi sono spiegato).
@manugal: Sono cinque e passa anni che non programmo più e non soon mai stato una cima, ma se non sbaglio if(int(n%11)) è "vero" solo se il numero NON è divisibile per 11, visto che n%11 è il resto della divisione per 11.
PS: Per curiosità posteresti il codice finale?
@leadergl: Come giustamente ha detto fuocofatuo è più ottimizzato solo per il calcolo manuale in base 10, anche se in effetti il tuo algoritmo è ricorsivo.
fuocofatuo
08-11-2005, 22:11
Hai ragione. Il suddetto algoritmo va bene per il calcolo manuale. Però se si volessero testare numeri >MAX_INT (2^32-1), in teoria uno potrebbe farlo trattando il numero immesso come array di cifre, senza mai convertirlo in numero (non so se mi sono spiegato).
Beh, è chiaro. Però non so se si può definire lo stesso algoritmo...
Chissà invece se esiste un criterio di divisibilità anche per la base due...
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.