配列には、従来のArrayオブジェクトのほかに
「型指定された配列」というものが使えます。
要するにC/C++で使う普通の配列です。
添え字は0から始まり、範囲外なら例外を投げます。
var a : int[]; //intの配列の宣言
a = new int[10]; //intの領域を10個分確保して初期化
print(a[9]); //0
print(a[10]); //例外発生
上のように宣言して
newで領域を確保します。
このとき初期化も同時に行うようです。
こんな風にも書けるようです。
var a = new int[10];
このとき、aはintの配列になります。
Arrayオブジェクトで初期化することもできます。
var a : int[] = [ 1, 2, 3 ];
print(a[2]); //3
print(a[3]); //例外発生
この例では大きさ3のintの配列になります。
C/C++と同じように多次元配列を表すために配列の配列が使えます。
var b : int[][]; //intの配列の配列を宣言
b = new (int[])[5]; //intの配列のアドレスを格納する領域5個分を確保
for(var i : int = 0; i < 5; i++) {
b[i] = new int[5]; //intの領域5個分確保
for(var j : int = 0; j < 5; j++)
b[i][j] = i + j;
}
print(b[4][4]);
5×5の配列を作って値を入れています。
上のような面倒なことをしなくても実は多次元配列が使えます。
var b : int[,]; //2次元配列を宣言
b = new int[5,5]; //5×5のintの領域を確保
for(var i : int = 0; i < 5; i++) {
for(var j : int = 0; j < 5; j++)
b[i,j] = i + j;
}
print(b[4,4]);
[ ]の中にカンマ(,)で区切って配列の大きさを指定、
あるいは要素にアクセスします。
次の例は、doubleの3×4×5の3次元配列の領域を確保しています。
var c : double[,,] = new double[3,4,5];
Arrayクラスのメンバが一部使えるようです。
var a : int[,,] = new int[3,4,5];
print(a.Length); //60(=3*4*5)
print(a.Rank); //3
var b : int[][] = new (int [])[5];
print(b.Length); //5
print(b.Rank); //1
print(a.GetLength(2)); //5
print(a.GetLowerBound(2)); //0
print(a.GetUpperBound(2)); //4
そのうち別ページで解説します。
2次元配列の例をベンチマークします。
題材は
じゃんけんで決着がつくまでの回数
です。500人でじゃんけんした場合にかかった時間を比較します。
array.js
---------------------------------------------------------
import System;
var t : int = Environment.TickCount;
var n : int; //最初の人数
var args : String[] = Environment.GetCommandLineArgs();
try {
...
n = parseInt(args[1]);
...
}
...
//m人がじゃんけんしたときにi人が残る確率を求める
var p = new Array();
p[2] = [ 0, 2 / 3, 1 / 3 ];
var q = new Array(); //q[m] = 1 - p[m][m]
q[2] = 2 / 3;
for(var m : int = 3; m <= n; m++) {
p[m] = new Array();
p[m][1] = p[m-1][1] * m / (m - 1) / 3;
q[m] = p[m][1];
for(var i : int = 2; i < m; i++) {
p[m][i] = p[m][i-1] * (m - i + 1) / i;
q[m] += p[m][i];
}
p[m][m] = 1 - q[m];
}
//n人がじゃんけんして1人が残るまでの回数の期待値を求める
var E = [ 0, 0 ];
for(var j : int = 2; j <= n; j++) {
var a : double = p[j][j];
for(i = 1; i < j; i++)
a += p[j][i] * (E[i] + 1);
E[j] = a / q[j];
}
print("E[" + n + "] : " + E[n]);
print((Environment.TickCount - t) + "ms");
上はArrayを使った場合です。821msかかりました。
janken2.js
---------------------------------------------------------
...
//m人がじゃんけんしたときにi人が残る確率を求める
var p : double[][] = new (double[])[n+1];
p[2] = new double[n+1];
p[2][1] = 2 / 3;
p[2][2] = 1 / 3;
var q : double[]; //q[m] = 1 - p[m][m]
q = new double[n+1];
q[2] = 2 / 3;
for(var m : int = 3; m <= n; m++) {
p[m] = new double[n+1];
...
}
...
これは配列の配列ば〜じょんです。360msかかりました。
えらく遅いですね。計算量は
O(n
2)のはずなのに。
janken3.js
---------------------------------------------------------
...
//m人がじゃんけんしたときにi人が残る確率を求める
var p : double[,] = new double[n+1,n+1];
p[2,1] = 2 / 3;
...
これは多次元配列ば〜じょんです。60msかかりました。
こちらの方がやはり速いですが、
それでもこんなにかかるかというのはなんなんでしょう。
ちなみにCで書いたところ0msと出ました。