2017-01-26 6 views
2

Я пытаюсь найти максимальный элемент в списке, не используя List.Max для школьного задания, используя приведенный ниже шаблон.Поиск элемента Maximum в списке с совпадением рисунков и рекурсией F #

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

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

Единственное решение этой проблемы я могу думать, атм

 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];;  

Есть ли способ я могу перейти от функции я построил, чтобы тот, который использует шаблон? Благодаря!

+2

Возможный дубликат [Как получить максимальное значение из списка с помощью функции, которая принимает два аргумента?] (Http://stackoverflow.com/questions/13474382/how-do-get-the-max -значение-с-а-лист-с-а-функции, которая принимает к-два-аргумента) –

ответ

4

Ваша вспомогательная функция должна делать работу, внешняя функция просто проверяет, что список не пуст, и если это не так, вызывает помощника, который должен быть чем-то вроде этого:

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

Обратите внимание, что вы так как вы сопоставления с последним аргументом функции вы можете удалить его и использовать function вместо matchwith:

let rec helper = function 
    | [] , m -> m 
    | x::xs, m -> helper (xs, max m x) 
1

вы могли бы пойти на кортеж пройти как, или просто применить вспомогательную функцию I n ваше основное совпадение (вместо предложения о запрете списка). Я включаю ответ для тех, кто может найти этот вопрос в будущем и не имеет четкого ответа.

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 

Используя складка:

let findMax l = l |> List.fold (fun maxValue x -> if x > maxValue then x else maxValue) (List.head l) 
3
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) 

Пример:

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

Пустой список не будет возвращать None.

0

Я не уверен, что точные правила вашего настроения, но максимальный список на самом деле просто List.reduce max. Таким образом,

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

Вам нужна аннотация типа, чтобы понравиться typechecker.

let inline listMax xs = List.reduce max xs 

также работает и является общим, поэтому он работает с, например, поплавки и строки.