2011-12-27 1 views
3

유형으로 int 행렬을 정의해야합니다. 행렬의 행 또는 행은 city을 나타내며 행렬의 요소는 행 도시와 열 도시 사이의 distance을 나타냄니다. 행렬의 크기가 변경 될 수 있지만 (도시를 추가하거나 제거 할 수 있음) 항상 작습니다.OCaml에서 배열,리스트 또는 맵으로 int 행렬을 정의 하시겠습니까?

int array array, int list list 사이 주저로 정의 map와 유형은 다음과

module MatOrd = struct 
    type t = string * string 
    let compare ((a, b): string * string) ((c, d) : string * string) = 
    if Pervasives.compare a c <> 0 
    then Pervasives.compare a c 
    else Pervasives.compare b d 
end 

module MatMap = Map.Make(MatOrd) 

그럼 int MatMap.t는 INT의 행렬을 나타낼 수있다. 이 정의의 장점은 도시의 이름을 매트릭스의 좌표로 직접 쓸 수 있다는 것입니다. int array arrayint list list이있는 경우에는 좌표계의 의미를 암기해야 할 것 같습니다 ...

게다가 배열과 패턴 매칭을 할 수없는 것은 사실입니까? 예를 들어, 우리는 쓸 수 없습니다 : 장점과 내가 언급 단점 여부와

match a_array with 
    [| first_element; the_rest_elements |] -> ... 

당신은 어떤 유형을 제안합니까?

+0

당신은'match a_array with [| first_element; the_rest_elements |] -> ...'이것은 배열의 요소에 접근하는 방식이 아니기 때문입니다. 'the_rest_elements'는 메모리에 존재하지 않으며 타입 시스템에 타입도 없습니다. 하지만 배열과 패턴 매칭을 완벽하게 수행 할 수 있습니다. –

답변

3

은 실제로 어떤 조작을 통해 구현해야하는지에 따라 다릅니다. 어떤 타입으로 계산할 것입니까?

예를 들어, min-plus multiplication과 같은 어딘가에서 구현 된 행렬 작업을 이용하면 가장 짧은 경로 문제를 해결하는 데 도움이 될 수 있습니다. 이 경우 행렬을 사용하고 도시 이름에서 행렬 좌표로 변환하는 별도의 함수 string -> int이 있어야합니다. 반면 계산이 부족한 데이터 저장소를 원한다면 위와 같은 유형의 Map이 더 적합 할 수 있습니다.

그것은 당신이 계산 원하는 것을 모르고 매우 통찰력있는 답변을 제공하기 어렵지만, 당신의 제안에 관해서 :

  • 기억 목록은 당신이 할 경우에 따라서 int list list 제한된 유틸리티
  • 을 가지고, 불변 차원 배열은, 조심 배열은 변경 가능한 참조로, 그 허식은, 그에 따라 처리되도록 다음과 후 :

    let a = Array.make 3 0;; 
    let a = b;; 
    b.(0) <- 42;; 
    

    ,379,732을 10은 42입니다.

    let m = Array.make 2 (Array.make 3 0);; 
    m : int array array = [|[|0; 0; 0|]; [|0; 0; 0|]|] 
    m.(0).(0) <- 1;; 
    - : unit =() 
    m;; 
    - : int array array = [|[|1; 0; 0|]; [|1; 0; 0|]|] 
    

    은 내부 make 호출이 먼저 평가됩니다, 같은 기준에 의해 공유 : 다른주의해야 할 점은 당신이 배열을 다음과 같은 방법을 만들 수 없습니다해야한다는 것입니다 수 있도록

    언어는 열망 평가 전략을 가지고 외부 배열의 세 줄. 행렬을 만드는 방법은 the FAQ을 참조하십시오.

그리고 그런데

, 당신은 배열에 대한 패턴 매칭을합니다 ( relevant manual section이 페이지 하단의 패턴을 보여줍니다) 할 수 있지만, 패턴 변수를 배치 할 때 배열의 차원을 존중해야합니다.고맙게도 _을 사용할 수 있으며 배열의 크기가 매우 작다고 말한대로.

+0

좋은 링크와 합리적인 답변, 일반적으로,하지만 나는 그 두 번째 글 머리 기호에서 "이름으로 전달"을 의미한다고 생각하지 않습니다. Ocaml은 "이름으로 전달"의미를 사용하지 않습니다. 다음은 "이름으로 전달"의미가 실제로 무엇인지에 대한 설명입니다. http://www.cs.sfu.ca/~cameron/Teaching/383/PassByName.html 또한 이 아니기 때문에이 이름과 대신 외부 생성자에 대한 인수는 값에 의해 전달되므로 (따라서 한 번만 평가 됨) 기본 2 차원 배열 생성이 실패합니다. –

+0

물론! 모호함/실수를 없애기 위해 길이를 수정했습니다. – huitseeker