2011-12-27 62 views
3

我需要定義一個int類型的矩陣。矩陣的一列或一行代表city,矩陣中的元素表示行城與列之城之間的distance。矩陣的維數可能會發生變化(我們可能會增加或刪除城市),但它總是很小。用OCaml中的數組,列表或映射定義int的矩陣?

我猶豫之間int array arrayint 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'既不存在於內存中,也不具有類型系統中的類型。但是你可以很好地與數組進行模式匹配。 – 2011-12-27 08:14:19

回答

3

這種或那種類型的適用性真的取決於你用什麼操作來實現它。你會用你的類型計算什麼?

例如,您可能想要利用在某處執行的矩陣操作,例如min-plus multiplication,這可能會幫助您解決最短路徑問題。在這種情況下,使用矩陣是有意義的,並且具有單獨的功能string -> int,其從城市名稱轉換爲矩陣座標。另一方面,如果你只想要一個計算稀缺的數據存儲,那麼類似上面那樣的Map類型可能更有意義。

很難給不知道你要計算什麼非常有見地的答案,但對於你的建議:

  • 記住名單是不可改變的,因此int list list具有有限效用
  • ,如果你做兩個維陣列,當心數組是可變的引用和做作相應處理,從而使後執行以下操作:

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

    a.(0)等於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此外,這是因爲它們是而不是通過名稱和相反,外部構造函數的參數是通過值傳遞的(因此只評估一次)näive2-d數組創建失敗。 – 2011-12-27 10:50:04

+0

當然!更正以消除任何含糊不清/錯誤 – huitseeker 2011-12-27 11:13:21