2017-11-05 14 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] 

シーケンスでも機能します。

この1つは唯一のリスト(ない系列)で動作し、非常に遅いことができます

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

関連する問題