Précédent   Forum du club des développeurs et IT Pro > Autres langages > Langages fonctionnels > Caml
Caml Forum d'entraide sur la programmation avec les langages fonctionnels Caml-Light et OCaml
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 01/10/2012, 22h29   #1
Wenneguen
Invité de passage
 
Maths Spé : MP
Inscription : août 2012
Messages : 11
Détails du profil
Informations professionnelles :
Activité : Maths Spé : MP

Informations forums :
Inscription : août 2012
Messages : 11
Points : 0
Points : 0
Par défaut Rendre une liste et modifier une référence en même temps

Bonjour,

je dois écrire une fonction réalisant l'addition de deux nombres définis par une une liste de chiffres.
Voilà ce que j'ai fait, mais comme je le craignais ça ne marche pas

let rec addition n1 n2 =

let retenue = ref 0
in

match (n1 , n2) with
([] , []) -> []
|([] , t::q) -> (t + !retenue):: (addition [] q)
|(t::q , []) -> (t + !retenue):: (addition [] q)
|(t1::q1 , t2::q2) -> (t1+t2 mod 10 + !retenue):: (addition q1 q2);
retenue:= ( t1+t2 - (t1+t2 mod 10) )/10
;;


retenue:= ( t1+t2 - (t1+t2 mod 10) )/10
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Cette expression est de type unit,
mais est utilisée avec le type int list.


Cette façon de faire est-elle impossible ?


Merci !
Wenneguen est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/10/2012, 00h27   #2
Ptival
Membre actif
 
Avatar de Ptival
 
Homme Valentin Robert
Étudiant
Inscription : juin 2004
Messages : 70
Détails du profil
Informations personnelles :
Nom : Homme Valentin Robert
Âge : 24
Localisation : Etats-Unis

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : juin 2004
Messages : 70
Points : 172
Points : 172
Code :
1
2
3
4
5
6
7
8
9
10
let rec addition n1 n2 =
  let retenue = ref 0 in
  match (n1 , n2) with
  | ([] , []) -> []
  | ([] , t::q) -> (t + !retenue) :: (addition [] q)
  | (t::q , []) -> (t + !retenue) :: (addition [] q)
  | (t1::q1 , t2::q2) ->
    (t1 + t2 mod 10 + !retenue) :: (addition q1 q2);
    retenue:= (t1 + t2 - (t1 + t2 mod 10))/10
A present, mes remarques (desole pour le manque d'accents) :

- je ne suis pas certain de la bonne priorite de (t1 + t2 mod 10). Ce n'est pas parce que tu ecris (t1+t2 mod 10) que ce sera ((t1 + t2) mod 10) et pas (t1 + (t2 mod 10)). Dans le doute je parenthese pour faciliter ma relecture.

- l'utilisation de la retenue dans ce code est douteuse. Par exemple, dans la branche finale, tu mets a jour la retenue _apres_ tous les calculs, ce qui ne sert a rien (puisque la retenue est une variable locale a la fonction addition).

Peut-etre que ce que tu veux c'est avoir :

Code :
1
2
3
4
5
    let tete = (t1 + t2 mod 10 + !retenue) in
    retenue:= (t1 + t2 - (t1 + t2 mod 10))/10;
    let queue = addition q1 q2 in
    tete :: queue
- ceci etant, il y a un probleme encore plus fondamental je pense avec ta variable retenue, car elle est remise a zero dans chaque appel recursif (ou plutot, ce n'est pas la meme variable a chaque fois), du coup il faudrait reorganiser le code ainsi :

Code :
1
2
3
4
5
6
7
8
let addition n1 n2 =
  let retenue = ref 0 in
  let rec addition_aux n1 n2 =
    match (n1 , n2) with
    ... (* appels recursifs a addition_aux *)
  in
  addition_aux n1 n2
- bref, tout ceci etant, on dirait que l'utilisation de references dans ton code fait plus de bien que de mal. Pourquoi ne pas tenter d'ecrire une version sans references ? Un squelette :

Code :
1
2
3
4
5
6
7
8
let addition n1 n2 =
  (* ret est la retenur courante *)
  let rec addition_aux n1 n2 ret =
    match (n1 , n2) with
    ... (* appels recursifs a addition_aux, utilise ret et met a jour dans les appels ou il faut *)
  in
  addition_aux n1 n2 0
---

EDIT : Et si tu souhaites vraiment rendre la valeur d'une retenue a la fin, il va falloir que tu precises quelle valeur tu veux renvoyer. Et tu peux la renvoyer sous forme d'une paire (resultat, retenue).

---

EDIT2 :

Je ne te donne pas de solution car ca ressemble a un devoir maison ou a un exercice d'entrainement, et ce serait mieux que tu y arrives seul.

Sinon autre remarque, si tu fais des additions de nombres de longueur arbitraire, tu n'es pas cense avoir de retenue finale :\ Donc il faudrait preciser ce que tu essaies de renvoyer...
Ptival est déconnecté   Envoyer un message privé Réponse avec citation 10
Réponse
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 04h46.


 
 
 
 
Partenaires

Hébergement Web