J'essaie de trouver l'élément maximum dans une liste sans utiliser List.Max pour un devoir scolaire en utilisant le modèle ci-dessous.

        let findMax l = 
        let rec helper(l,m) = failwith "Not implemented"

        match l with
        | [] -> failwith "Error -- empty list"
        | (x::xs) -> helper(xs,x) 

La seule solution au problème auquel je peux penser, atm est

        let rec max_value1 l =
          match l with
          |[] -> failwith "Empty List"
          |[x] -> x
          |(x::y::xs) ->  if x<y then max_value1 (y::xs)
                else max_value1 (x::xs)

        max_value1 [1; 17; 3; 6; 1; 8; 3; 11; 6; 5; 9];;    

Est-il possible de passer de la fonction que j'ai créée à celle qui utilise le modèle? Merci!

4
SharpTooth 26 janv. 2017 à 03:39

4 réponses

Meilleure réponse

Votre fonction d'assistance devrait faire le travail, la fonction externe valide simplement que la liste n'est pas vide et si ce n'est pas le cas, appelle l'aide, qui devrait être quelque chose comme ceci:

let rec helper (l,m) = 
    match (l, m) with
    | []   , m -> m
    | x::xs, m -> helper (xs, max m x)

Notez que vous, puisque vous correspondez au dernier argument de la fonction, vous pouvez le supprimer et utiliser function au lieu de match with:

let rec helper = function
    | []   , m -> m
    | x::xs, m -> helper (xs, max m x)
6
Gus 26 janv. 2017 à 05:44

Vous pouvez choisir un tuple pour passer les deux, ou simplement appliquer la fonction d'assistance dans votre correspondance principale (au lieu de la clause de garde de liste vide). J'inclus la réponse pour quelqu'un qui pourrait trouver cette question à l'avenir et ne pas avoir de réponse claire.

let findMax l = 
   let rec walk maxValue = function
       | [] -> maxValue
       | (x::xs) -> walk (if x > maxValue then x else maxValue) xs
   match l with 
   | [] -> failwith "Empty list"
   | (head::tail) -> walk head tail

findMax [1; 12; 3; ] //12

Utilisation du pli:

let findMax l = l |> List.fold (fun maxValue x -> if x > maxValue then x else maxValue) (List.head l)
3
Asti 26 janv. 2017 à 06:08

Je ne suis pas sûr de ce que sont les règles exactes de votre attribution, mais le maximum d'une liste est en réalité juste List.reduce max. Alors

let listMax : int list -> int = List.reduce max

Vous avez besoin de l'annotation de type pour plaire au vérificateur de type.

let inline listMax xs = List.reduce max xs

Fonctionne également et est générique, donc cela fonctionne avec par ex. les flotteurs et les cordes aussi.

1
Lars 27 janv. 2017 à 13:22
let findMax l = 
  let rec helper(l,m) =
    match l with
    | [] -> m
    | (x::xs) -> helper(xs, if (Some x > m) then Some x else m)
  helper (l,None)

Exemple:

[-2;-6;-1;-9;-56;-3] |> findMax  
val it : int option = Some -1

Une liste vide renverra Aucun.

4
Kevin 26 janv. 2017 à 06:21