スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

F#入門第32回(命令型プログラミング(4)配列(array) (2))

今回のお題は「命令型プログラミング(4)配列(array) (2)」です。
 
まずは宿題の解答から
次のように、配列を定義したとき、それぞれどんな配列ができるでしょうか?
またk1とk2の違いはなんでしょうか。
 
let k1 = [| 
            yield [|5;6|]
            yield [|5;6|]
            yield [|5;6;7|]
           |]
 
let k2 = [|
            let t = [|5;6|]
            for i in 1 .. 2 do
                yield t
            yield [|5;6;7|]
           |]
 
それでは解説ですが、どちらもこれは、要素として、int arrayをもつarrayです。型としては、int array array と表示されます。また、arrayの代わりに[]も使えます。つまりint array array もint [] [] も同じものです。
F#interactive で表示してみます。
 
val k1 : int array array = [|[|5; 6|]; [|5; 6|]; [|5; 6; 7|]|]
 
val k2 : int array array = [|[|5; 6|]; [|5; 6|]; [|5; 6; 7|]|]
 
配列の中に、配列が入れ子になっている、このような配列をjagged arraysといいます。
アクセスの方法は例えばk1.[0]で一つ目の要素[|5;6|](配列なので ポインタ表現であることに注意)を得ることができます。
 

 
> printfn "%A" k1.[0];;
[|5; 6|]
val it : unit = ()
 
さらに、そのなかの要素にアクセスするには.[index]を続けます。
 
> printfn "%A" k1.[0].[1];;
6
val it : unit = ()
 
さてk1,k2の違いですが、k2においては、0番目の要素[|5;6|]と1番目の要素[|5;6|]は、まったく同じtから生成されています。配列はポインタ表現ですので、0番目の要素と1番目の要素は、メモリ上の同じものが表示されていることになります。
ちなみに、k2.[0].[1]を変更してみます。
 
> k2.[0].[1] <- 100;;
val it : unit = ()
 
> k2;;
val it : int array array = [|[|5; 100|]; [|5; 100|]; [|5; 6; 7|]|]
 
見ての通り、k2.[1].[1]も100となっています。
k1では、このようなことは起こりません。これが、k1とk2の違いです。
 
さて、もとの
val k1 : int array array = [|[|5; 6|]; [|5; 6|]; [|5; 6; 7|]|]
val k2 : int array array = [|[|5; 6|]; [|5; 6|]; [|5; 6; 7|]|]
の状態でk1とk2を等号比較してみましょう。
 
> k1 = k2 ;;
val it : bool = true
 
ということで、配列同士は、形が同じで各要素がすべて等しいとき、等しいと判断されます。
 
ここまでが、宿題がらみのjagged arraysの紹介ですが、多次元配列でよくつかわれるのは、配列の配列でも配列内の配列の要素数がすべて同じであるタイプです。
つまり
[| 
    [|5;6|];
    [|5;6|];
    [|5;6|];
  |]
のようなタイプです。並べると長方形型になるので、Rectangular arraysと呼ばれます。
こちらに対しては、Array2Dモジュールというのが準備されていて、この中の関数を使って生成するのが一般的です。
 

 
let a2 :float[,] = Array2D.zeroCreate 3 2;;
val a2 : float [,] = [[0.0; 0.0]
                      [0.0; 0.0]
                      [0.0; 0.0]]
 
zeroCreateでは、型注釈が必須です。さらに、型がjaggedの時の[][] ではなく[,]になったことに注意してください。
(他にも生成用の関数があるので、調べてみてください。)
アクセスするには次のように .[rowIndex,colIndex]を付けます。
 
> a2.[2,0] <- 1.0;;
val it : unit = ()
 
> a2;;
val it : float [,] = [[0.0; 0.0]
                      [0.0; 0.0]
                      [1.0; 0.0]]
 
次にArraysに対してのパターンマッチングです。
例として最初の要素(index 0の)を表示する関数を考えます。
 
let dispfirst arr =
    match arr with
    |null
    |[||] -> printfn "最初の要素が存在しません"
    | _ -> printfn "最初の要素は%Aです。" arr.[0]
 
実行例
 
> dispfirst [|2;3|];;
最初の要素は2です。
val it : unit = ()
 
配列はnullであるという場合がありうることに留意してください。
また[|x|]や、[|x;y|]というような形のパターンマッチも可能です。
 
それでは宿題です。arrays(配列)int []型 が与えられたとき、要素数(長さ)が5のときだけ、和をSomeでくるんで返し、それ以外のときはNoneを返す関数 sum5arrayを次につづけて定義してください。
let sum5array (a : int []) =
スポンサーサイト

テーマ : プログラミング
ジャンル : コンピュータ

コメントの投稿

非公開コメント

プロフィール

T GYOUTEN

Author:T GYOUTEN
F#と英単語とフリーソフトと読書に興味があります。
ホームページでフリーソフトも公開しています。どぞ御贔屓に。

最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
フリーエリア
フリーエリア
blogram投票ボタン
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QRコード
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。