+ Répondre à la discussion
Affichage des résultats 1 à 2 sur 2
  1. #1
    Invité de passage
    Homme Profil pro
    Étudiant
    Inscrit en
    août 2012
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 21
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : août 2012
    Messages : 45
    Points : 4
    Points
    4

    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 !

  2. #2
    Membre actif Avatar de Ptival
    Homme Profil pro
    Étudiant
    Inscrit en
    juin 2004
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : juin 2004
    Messages : 70
    Points : 168
    Points
    168

    Par défaut

    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...

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •