|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Dec 2006
Messaggi: 3808
|
[C] somma interi con ricorsione - migliorare programma già fatto
Codice:
#include <stdio.h> int sommaTraInteri(int myA, int myB, int*, int*); int main(){ int mA=12; int mB=16; int sum=0; int cur=mA+1; printf("\n%d\n",sommaTraInteri(mA,mB,&sum,&cur)); } int sommaTraInteri(int myA, int myB, int *sum, int *cur){ if(*cur>myA && *cur<myB){ *sum=*sum+*cur; *cur=*cur+1; sommaTraInteri(myA,myB,sum,cur); } else return *sum; } |
![]() |
![]() |
![]() |
#2 |
Member
Iscritto dal: Aug 2005
Messaggi: 168
|
Codice PHP:
![]() |
![]() |
![]() |
![]() |
#3 | |
Senior Member
Iscritto dal: Dec 2006
Messaggi: 3808
|
Quote:
in pratica hai tolto il passaggio per riferimento e fatto un "trenino" di int con il return, sembra più corta in effetti ... EDIT: il programma ha una logica errata, mi da un risultato sbagliato Ultima modifica di Freaxxx : 05-09-2011 alle 09:33. |
|
![]() |
![]() |
![]() |
#4 |
Member
Iscritto dal: Aug 2005
Messaggi: 168
|
Puoi darmi qualche dettaglio in più? Con l'esempio 12-16 mi da 42 che è la risposta giusta se non ho capito male il problema.
|
![]() |
![]() |
![]() |
#5 | |
Senior Member
Iscritto dal: Dec 2006
Messaggi: 3808
|
Quote:
non riesco a capire, provo a compilarlo "a mano" con gcc. |
|
![]() |
![]() |
![]() |
#6 |
Senior Member
Iscritto dal: Dec 2006
Messaggi: 3808
|
sempre 58 mi da.
edit: in pratica include nella somma anche l'estremo mB, il risultato dovrebbe essere 42, ma viene 58 cioé 42+16 Ultima modifica di Freaxxx : 05-09-2011 alle 10:04. |
![]() |
![]() |
![]() |
#7 |
Senior Member
Iscritto dal: May 2001
Messaggi: 12840
|
Codice:
int Summer( int a, int b ) { if (a>=b) return 0; if (b-a==1) return 0; if (b-a==2) return a+1; return a+1 + Summer(a+1, b); } |
![]() |
![]() |
![]() |
#8 |
Member
Iscritto dal: Aug 2005
Messaggi: 168
|
Non ho codeblocks qua ma usando questo
http://codepad.org/txumHNmt Mi dà il risultato giusto. Non sò che dire. |
![]() |
![]() |
![]() |
#9 |
Member
Iscritto dal: Aug 2005
Messaggi: 168
|
Prova così sennò.
Codice PHP:
|
![]() |
![]() |
![]() |
#10 |
Senior Member
Iscritto dal: Dec 2006
Messaggi: 3808
|
adesso installo linux da qualche parte e provo con altre versioni di gcc, ho paura che questo sia un bug ...
|
![]() |
![]() |
![]() |
#11 |
Senior Member
Iscritto dal: Dec 2006
Messaggi: 3808
|
compilato sotto la beta1 attuale di Ubuntu
Codice:
tux@tux-VirtualBox:~$ gcc -v Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.6.1/lto-wrapper Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.6.1-7ubuntu2' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++,go --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-plugin --enable-objc-gc --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu Thread model: posix gcc version 4.6.1 (Ubuntu/Linaro 4.6.1-7ubuntu2) |
![]() |
![]() |
![]() |
#12 |
Senior Member
Iscritto dal: Jul 2005
Città: Bologna
Messaggi: 1130
|
C'è da dire che la tua versione iniziale mi pare sia tail-recursive (involontariamente, credo), mentre le altre che ho visto successivamente mi pare non lo siano.
Io farei una roba tipo (se non ho scritto stronzate): Codice:
#include <stdio.h> int SumRangeAux(int a, int b, int accum) { return a >= b ? accum : SumRangeAux(a + 1, b, accum + a); } int SumRange(int a, int b) { return SumRangeAux(a + 1, b, 0); } int main() { int a = 12, b = 16; printf ("%d\n", SumRange(a, b)); return 0; }
__________________
-> The Motherfucking Manifesto For Programming, Motherfuckers |
![]() |
![]() |
![]() |
#13 |
Member
Iscritto dal: Aug 2005
Messaggi: 168
|
No, hai ragione, la mia non è tail-recursion. La soluzione iniziale immagino possa essere definita tail-recursion ma non usa minimamente la ricorsione, si passa direttamente il puntatore al risultato in giro. Non ha per niente senso così.
Se vuoi qualcosa con la tail-recursion l'unica cosa che mi viene in mente è Codice PHP:
La mia versione finale è: Codice PHP:
|
![]() |
![]() |
![]() |
#14 |
Senior Member
Iscritto dal: Oct 2001
Messaggi: 11471
|
C'è una formula facile da ricordare che permette di sommarli senza ricorsione o cicli. Però tiene conto anche degli estremi quindi nel tuo caso ci si deve ricordare di aggiungere e sottrarre 1.
Codice:
#include <stdio.h> int sum(int from, int to) { return ((to * to) - (from * from) + from + to) / 2; } int main(int argc, char** argv) { printf("%d", sum(12 + 1, 16 - 1)); } |
![]() |
![]() |
![]() |
#15 |
Senior Member
Iscritto dal: Jul 2005
Città: Bologna
Messaggi: 1130
|
Sì beh non è tanto questione di bello o brutto. Sono due soluzioni molto diverse in termini di complessità di spazio, ed è bene conoscere questi aspetti, soprattutto se uno sta facendo esercizi per imparare.
__________________
-> The Motherfucking Manifesto For Programming, Motherfuckers |
![]() |
![]() |
![]() |
#16 | |
Senior Member
Iscritto dal: Aug 2001
Città: San Francisco, CA, USA
Messaggi: 13827
|
Quote:
![]()
__________________
GPU Compiler Engineer |
|
![]() |
![]() |
![]() |
#17 | |
Senior Member
Iscritto dal: Aug 2001
Città: San Francisco, CA, USA
Messaggi: 13827
|
Quote:
![]() Codice:
#include <stdio.h> int sommaTraInteri(int myA, int myB, int*, int*); int main(){ int mA=12; int mB=16; int sum=0; int cur=mA+1; printf("\n%d\n",sommaTraInteri(mA,mB,&sum,&cur)); } int sommaTraInteri(int myA, int myB, int *sum, int *cur){ if(*cur>myA && *cur<myB){ *sum=*sum+*cur; *cur=*cur+1; sommaTraInteri(myA,myB,sum,cur); } else return *sum; } Codice:
return sommaTraInteri(...blah) ;
__________________
GPU Compiler Engineer Ultima modifica di AnonimoVeneziano : 06-09-2011 alle 09:22. |
|
![]() |
![]() |
![]() |
#18 | |
Senior Member
Iscritto dal: May 2001
Messaggi: 12840
|
Quote:
Inoltre per come la vedo io, se devi scrivere codice tail-recursive, a meno che non ti venga naturale farlo, tantovale usare direttamente l'iterazione. La via più naturale, per come la vedo io, è usare la ricorsione classica con lo stack delle chiamate, anche se questo può essere meno efficiente, ma secondo me è utile per capire bene il meccanismo. Ultima modifica di WarDuck : 06-09-2011 alle 11:16. |
|
![]() |
![]() |
![]() |
#19 | ||
Senior Member
Iscritto dal: Jul 2005
Città: Bologna
Messaggi: 1130
|
Quote:
Quote:
E alla fine in termini pratici dipende dal linguaggio: in C usare la ricorsione in questo modo non è il modo idiomatico di esprimere questo algoritmo. In Haskell magari la situazione cambia... e allora è bene sapere la differenza tra i vari approcci e non solo avere "qualcosa che funziona".
__________________
-> The Motherfucking Manifesto For Programming, Motherfuckers |
||
![]() |
![]() |
![]() |
#20 | |
Senior Member
Iscritto dal: Aug 2001
Città: San Francisco, CA, USA
Messaggi: 13827
|
Quote:
Codice:
lol :: Int -> Int -> Int lol a b | a < (b-1) = (a+1) + k | a >= b-1 = 0 where k = lol (a+1) b main = do putStrLn $ show $ lol 20 25 ![]()
__________________
GPU Compiler Engineer |
|
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 07:24.