2017-11-05 1 views
1

주어진 요소가 실제로 목록에있는 위치를 알려주는 간단한 함수를 만들었습니다. 첫 번째 위치는 0입니다 :목록의 요소 찾기

let rec foo79 = 
fun k l -> 
    match k, l with 
    | k, []   -> failwith "What you are lookig for is not here" 
    | k, (x::xs) -> if  x = k then 0 
         else 1 + foo79 k xs 

간단하고 작동합니다 (그렇다고해도 모든 개선 제안은 환영합니다!). 나는이 기능을 수행하는 데 실패 무엇

, 그것은 x 목록에 다수에게 번 발생하는 경우에, 저에게x위치를 알 수 있도록하는 것입니다. 내 시도는 지금까지 해결책에 근접하지 않습니다. 나는 실제로 당신을 내가 추구하는 접근 방식의 예가되도록 게시하고 있습니다.

let rec foo79b = 
fun k l -> 
    match k, l with 
    | k, []   -> failwith "What you are lookig for is not here" 
    | k, (x::xs) -> if  x = k & (x::xs) then 1 + foo79b k xs 
         elif x = k & []  then 0 
         else 1 + foo79b k xs 

답변

2

함수는 결과 목록에 누적기를 사용할 수 있도록 위치 목록을 반환해야합니다. 동시에 대신 호출 사이트에서 합계 할 필요없이 인덱스를 밟아 다른 보조 매개 변수를 사용할 수 있습니다 :

let findAllPos elem lst = 
    let rec foo79 = 
     fun k l i acc -> 
      match k, l with 
      | k, []  -> acc 
      | k, (x::xs) -> if x = k then foo79 k xs (i+1) (i::acc) 
          else   foo79 k xs (i+1)  acc 
    foo79 elem lst 0 [] 

이 방법은 간단하게 더 중요한 솔루션 tail recursive하게합니다. 당신이 내게 첫 번째 함수를 호출하려고하지 않는다면 foo79 400000 [0..400000]을 시도해보고 난 후 findAllPos 400000 [0..400000]을 시도해보십시오.

+0

내가 출력으로 목록을 만들 생각하지 않았다. 소중한 제안에 감사드립니다! – Worice

1
let positions (x: 'a) (xs: 'a seq) : int seq = 
    xs 
    |> Seq.mapi (fun i y -> if y = x then Some i else None) 
    |> Seq.choose id 

// [0; 0; 2; 3; 4; 0; 6] |> positions 0;; 
// val it : seq<int> = seq [0; 1; 5] 

너무 작동합니다.

이것은 단지 목록 (하지 순서)와 함께 작동하고 매우 느릴 수 :

let positions' (x: 'a) (xs: 'a list) : int list = 
    [0..(Seq.length xs - 1)] 
    |> List.filter (fun i -> xs.[i] = x) 

// [0; 0; 2; 3; 4; 0; 6] |> positions' 0;; 
// val it : int list = [0; 1; 5] 
+0

예를 들어 주셔서 감사합니다! – Worice