3

関数にリストを入力しようとすると、以下の再帰で f# を使用して要素の前半が取り除かれたリストが送信されますが、理解できない基本ケースの問題が発生し続けます。何かご意見は?2 番目のシャドウ リストを使用して、リストの途中まで進む必要がある距離をカウントしています (一度に 2 つの要素を削除することにより)。

let rec dropHalf listToDrop shadowList = 
    match shadowList with
    | [] -> listToDrop
    | shadowHead2::shadowHead1::shadowTail -> if shadowTail.Length<=1 then listToDrop else 
                                    match listToDrop with 
                                    |[] -> listToDrop
                                    |listToDropHead::listToDropTail -> dropHalf listToDropTail shadowTail
4

4 に答える 4

2
let rec dropHalf listToDrop shadowList = 
    match shadowList with
    | [] -> listToDrop
    | shadowHead2::[] -> listToDrop   (* odd number! *)
    | shadowHead1::shadowHead2::shadowTail -> 
        match listToDrop with 
        | [] -> listToDrop   (* should never happen? *)
        | listToDropHead::listToDropTail -> dropHalf listToDropTail shadowTail

私はF#を使用していないのではないかと思いますが、それはocamlに似ているので、以下があなたが探しているものに近いことを願っています(おそらくコメント形式が変更されましたか?!)。アイデアは、あなたが影を使い果たすとき、あなたは終わったということです。コードはほぼそこにありましたが、シャドウテールの長さのテストは意味がありませんでした。

これは誰もが「実生活で」書くようなものではないことを強調したいのですが、あなたはいくつかの奇妙な要件と戦っているように思えます。

于 2012-05-22T01:31:26.053 に答える
1

一般的な経験則としてLength、リストを呼び出している場合は、自分がしていることを行うためのより良い方法がある可能性が最も高いです。 Lengthリスト全体を反復する必要があるため、O(n) です。

let secondHalf list =
    let rec half (result : 'a list) = function
        | a::b::sx -> half result.Tail sx
        // uncomment to remove odd value from second half
        // | (a::sx) -> result.Tail 
        | _ -> result

    half list list
于 2012-05-22T16:29:38.153 に答える
1

元のリストと同じ長さのシャドウ リストを使用し、これらのリストから異なる割合で要素を削除するため、補助関数を作成することをお勧めします。

let dropHalf xs =
    let rec dropHalf' ys zs =
      match ys, zs with
      | _::_::ys', _::zs' -> dropHalf' ys' zs'
      | _, zs' -> zs' (* One half of the shadow list ys *)
    dropHalf' xs xs

リストを 2 回トラバースする必要がない場合は、次の解決策の方が簡単です。

let rec drop n xs =
   match xs, n with
   | _ when n < 0 -> failwith "n should be greater or equals to 0"
   | [], _ -> []
   | _, 0 -> xs
   | _::xs', _ -> drop (n-1) xs'

let dropHalf xs =
    xs |> drop (List.length xs/2)

別の簡単な解決策では、余分なスペースが必要ですが、再帰を使用する必要はありません。

let dropHalf xs = 
    let xa = Array.ofList xs
    xa.[xa.Length/2..] |> List.ofArray
于 2012-05-22T02:13:48.473 に答える
0

これがあなたが説明したことを行うサンプルです。

open System
open System.Collections.Generic

let items = seq { 1 .. 100 } |> Seq.toList

let getBackOfList ( targetList : int list) = 
    if (targetList.Length = 0) then 
        targetList
    else
        let len = targetList.Length
        let halfLen = len / 2
        targetList |> Seq.skip halfLen |> Seq.toList

let shortList = items |> getBackOfList

("Len: {0}", shortList.Length) |> Console.WriteLine

let result = Console.ReadLine() 

お役に立てれば

于 2012-05-22T01:31:38.453 に答える