2013-11-26 6 views
3

정수 목록을 인수로 취하여 모든 값을 비교하여 가장 큰 값을 반환하는 함수를 만들고 싶습니다. C#에서는 목록의 모든 값을 순회하면서 변수에 가장 큰 것을 저장하고 반환합니다. F #이 비슷하게 작동하기를 기대하지만 문법은 나에게 적합 할 것입니다. 내 코드는 다음과 같습니다. 또한 max2는 2 개의 값을 비교하여 가장 큰 값을 반환하는 함수입니다.루프 내부 함수의 값 비교

let max_list list = 
    let a = 0 : int 
    match list with 
    | head :: tail -> (for i in list do a = max2 i a) a 
    | [] -> failwith "sry";; 
+1

I을 단순히''List ''를 호출하기를 원하지 않는다고 가정하십시오. max'] (http://msdn.microsoft.com/en-us/library/vstudio/ee370242.aspx), 맞지? – svick

+0

이 맞습니다. – Jacco

답변

12

당신은 mutable 변수를 사용하여 그냥 C#에서처럼, for 루프를 사용하여 코드를 작성할 수 있습니다. 그러나 F # 및 기능 개념을 배우기 위해이 작업을 수행하는 경우 재귀를 사용하는 것이 좋습니다.

이 경우 재귀 함수는 약간 길지만 패턴 매칭을 포함한 주요 개념을 보여줍니다. 따라서 트릭을 학습하는 것이 더 복잡한 F # 코드를 작성할 때 유용합니다.

중요한 아이디어는 지금까지 발견 된 가장 큰 값을 취하여 목록의 끝에 도달 할 때까지 재귀 적으로 호출하는 함수를 작성하는 것입니다.

let max_list list = 
    // Inner recursive function that takes the largest value found so far 
    // and a list to be processed (if it is empty, it returns 'maxSoFar') 
    let rec loop maxSoFar list = 
    match list with 
    // If the head value is greater than what we found so far, use it as new greater 
    | head::tail when head > maxSoFar -> loop head tail 
    // If the head is smaller, use the previous maxSoFar value 
    | _::tail -> loop maxSoFar tail 
    // At the end, just return the largest value found so far 
    | [] -> maxSoFar 
    // Start with head as the greatest and tail as the rest to be processed 
    // (fails for empty list - but you could match here to give better error) 
    loop (List.head list) (List.tail list) 

마지막으로 인터페이스를 통해 일반 비교를 사용하므로 속도가 느려집니다. let inline max_list list = (...)을 사용하면 기능을 빠르게 할 수 있습니다. 그런 식으로 코드는 int과 같은 기본 유형과 함께 사용할 때 기본 비교 명령어를 사용합니다 (이 경우는 실제로 특별한 경우입니다 - 일반적인 문제는 실제로 발생하지만 일반 비교에서는 실제로 발생합니다)

+0

항상 들었던 F #이 재귀에 대해 많이 감사합니다.이 예제에 대한 감사는 매우 유용합니다. – Jacco

+0

실제로는 기존 함수를 대부분 작성할 수 있기 때문에 재귀 * * *가 필요하지 않습니다.이 경우 List.max 만 사용할 수 있으며 대부분의 경우 기존 함수가 있습니다. 그러나 이미 존재하지 않는 무언가가 필요하다면 재귀를 알면 좋습니다. –

3

또한 다음을 사용하여 멋진 한 줄 짜기를 작성할 수 있습니다. 감소 : 항목의 값이 함수 MAX2에 의해 발견된다 당신의 의도가 목록에있는 항목의 최대 값을 찾을 수있을 것입니다 경우

let max_list list = List.reduce (fun max x -> if x > max then x else max) 
0

다음이 방법을 작동합니다

let findMax list = 
    list 
    |> List.map (fun i -> i, max2 i) 
    |> List.maxBy snd 
    |> fst