2017-09-21 4 views
1

J'ai une fonction personnalisée qui ajoute list2 à list1.Fonction d'ajout personnalisée F #

let append ls1 ls2 = 
    let rec loop ls ls1 ls2 = 
     match ls1, ls2 with 
     | _, hd::tl -> 
      loop (hd::ls) ls1 tl 
     | hd::tl, _ -> loop (hd::ls) tl ls2 
     | _ -> ls 
    loop [] ls1 ls2 

Cela fonctionne très bien. Mais le problème est quand je l'appelle la fonction

let appended = append [1;2;3;4;5] [6;7;8;9;10] 

au lieu de retourner [1;2;3;4;5;6;7;8;9;10] il retourne

[5;4;3;2;1;10;9;8;7;6] 

Il les deux listes, inverse.

+0

Et quelle est votre question? Si c'est à propos du mauvais résultat alors essayez encore, et rappelez-vous que 'hd :: tl' est comme attacher un' hd' à la tête de 'tl', pas ajouter à la fin de celui-ci – xuanduc987

+0

Le résultat souhaité est [1; 2; 3; 4; 5; 6; 7; 8; 9; 10] –

+0

En quoi cette question est-elle différente de celle d'hier? S'il vous plaît voir les réponses là-bas. – dumetrulo

Répondre

1

Vous devez inverser la liste. Une façon d'aller à la solution est de penser à quoi ressemblerait une fonction rev. Voici une première tentative:

let rec rev lst = 
    match lst with 
    | h::t -> (rev t)@[h] 
    | [] -> [] 

Cette fonction inverse une liste, mais maintenant nous allons faire une autre version qui utilise un accumulateur, cela signifie qu'au lieu d'utiliser une liste vide dans la dernière ligne, nous utiliserons un paramater d'addition:

let rec rev lst acc = 
    match lst with 
    | h::t -> rev t (h::acc) 
    | [] -> acc 

Alors maintenant, nous devons passer la liste vide comme paramètre:

rev [1..4] [];; 

val il: int list = [4; 3; 2; 1]

Vous pouvez vous demander pourquoi avons-nous besoin d'une telle fonction, eh bien cette fonction est tail recursive mais ce n'est pas votre question, vous cherchez à ajouter deux listes. Il s'avère que c'est 90% de la fonction que vous recherchez.

Si au lieu de passer une liste vide vous passez la deuxième liste:

rev [1..4] [5..8];; 

val il: int list = [4; 3; 2; 1; 5; 6; 7; 8]

Assez proche, mais oui, la première liste est inversée, ok, mais nous avons cette fonction qui peut renverser des listes, donc nous allons inverser la première liste:

rev (rev [1..4] []) [5..8] ;; 

val il: int list = [ 1; 2; 3; 4; 5; 6; 7; 8]

Grand, maintenant ce rev pourrait être notre fonction loop:

let append lst1 lst2 = 
    let rec rev lst acc = 
     match lst with 
     | h::t -> rev t (h::acc) 
     | [] -> acc 
    rev (rev lst1 []) lst2 

qui fonctionne comme prévu, mais notez que nous sommes en train d'appeler deux fois notre fonction rev paramétrés. J'espère que vous aurez une idée de la façon dont la programmation fonctionnelle vous permet de combiner des fonctions afin de résoudre différents problèmes. Dans ce cas, nous combinons une fonction avec elle-même.

2

code suivant a fonctionné pour moi

let rec append list1 list2 = 
    match list1, list2 with 
    | hd::tl, _ -> hd::(append tl list2) 
    | _, hd::tl -> hd::(append list1 tl) 
    | _ -> [] 

La sortie de code suivant est:

let List1 = [1; 3; 5]; 
    let List2 = [7] 
    printf "%A" append List1 List2 

est

[1; 3; 5; 7]