2014-01-13 3 views
2

어떻게 항목을 목록에서 위로 이동합니까?
입력 목록과 같습니다 let list = [1;2;3;4;5]
그리고 출력 목록은 다음처럼 보일 것이다
[1;2;3;5;4]
.........>목록에서 항목 위로 이동

[2;1;3;4;5]
...>......

플롯 트위스트 : 나는 할 수 있도록하려면 목록의 모든 색인을 이동하려면

내가 아는 바로는 이것은 F # 또는 함수형 언어로하는 것을 목표로하지는 않지만 내 프로그램에 반드시 있어야합니다.
나는 이것이 재귀와 higher order (HO) 함수를 사용하여 수행 될 수 있다고 믿지만 HO의 knowlegde가 매우 제한적이어서 재귀를 사용하여 이것을 해결하려고 시도했다.

목록에서 항목을 아래로 이동 내 접근 방식과 같이 인수로 인덱스 및 목록과 간단한 재귀 포함

그러나

let rec moveDownAt index list = 
    match index, list with 
    | -1, _ -> list 
    | 0, h1::h2::t -> h2::h1::t 
    | index, h::t -> h::moveDownAt (index - 1) t 
    | _, [] -> list 

, 나는 "이전을 참조 할 필요가 다른 방향으로 이동을 머리 "와 나는 세 번째 매치 라인에 문제가 있다고 가정합니다. | index, h::t -> h::moveDownAt (index - 1) t 내가 h :를 수행하는 곳 : 목록에 헤드를 추가 했으므로 (그 인수를 추가하면 이전 다음 호출이 될 것입니다).

답변

2

두 요소의 전환 지점은 하나가 위로 이동하고 하나가 아래로 이동한다는 것을 의미합니다. 이 문제를 해결합니다 다음 코드를 사용
간단한 :

let moveUpAt index list = moveDownAt (index-1) list 

이 인덱스를 만드는 대체 할 것이다 "까지 이동하는 인덱스 '로 전환"인덱스가 아래로 이동하는 방법 "을 참조하십시오.

1

기본 아이디어는 다음과 같습니다. 우선 목록의 n 요소를 반환하십시오. 그런 다음 나머지 요소를 추가하십시오 (이미 반환 한 이후 n 요소 제외). 여기 코드는 다음과 같습니다 index이리스트의 길이를 벗어나는 경우, ArgumentException가 발생합니다

let MoveToTop index xs = 
    List.nth xs index   // take nth item 
    ::       // and prepend it to the beginning of the 
           // original list, except the nth element 
    (
     xs      // original data 
     |> List.mapi 
      (fun i x -> i, x) // associate each element with its ordinal index 
     |> List.filter 
      (fun (i, _) -> i <> index) // allow only the elements whose index 
             // is not equal to requested index 
     |> List.map snd   // remove the index from the data 
           // as we no longer need it 
    ) 

// test 
[1; 2; 3; 4; 5] 
|> MoveToTop 1 // don't forget, the index is zero-based 
|> printfn "%A" 
// output: [2; 1; 3; 4; 5] 

하는 것으로.

재귀 알고리즘도 가능하지만 과도한 데이터 생성 및 과도한 계산 수행으로 인해 성능이 떨어집니다.