基礎プログラミング

基礎プログラミング
第9回(2007年5月14日)
数値データと配列,多次元配列
配列のコピー
配列の要素の検索と並び替え
(ソート)
2次元配列(行列)
1
配列の「コピー」は=でできる??

1:
2:
3:
4:
5:
6:
7:
確認プログラム(1:~7:は行番号)
int[] orig, copy;
orig = new int[3]{2,3,5};
copy = new int[3];
copy = orig;
for(int i=0;i<3;i++) copy[i] *= 2;
foreach(int n in orig) Console.WriteLine(n);
foreach(int n in copy) Console.WriteLine(n);
2
1: for(int
2:
3:
4:
int[] =
orig
copy
orig,
=i=0;i<3;i++)
new
new
orig;
copy;
int[3]{2,3,5};
int[3];copy[i]*=2;
5:
int[] 型の
変数orig
int[] 型の
変数copy
0
0
1
2
4
2
6
3
10
5
1
2
3
本当に配列を「コピー」するには

1:
2:
3:
4:
5:
6:
7:
(1:~7:は行番号)
int[] orig, copy;
orig = new int[3]{2,3,5};
copy = new int[3];
for(int i=0;i<3;i++) copy[i] = orig[i];
for(int i=0;i<3;i++) copy[i] *= 2;
foreach(int n in orig) Console.WriteLine(n);
foreach(int n in copy) Console.WriteLine(n);
4
1: for(int
2:
3:
int[] =
orig
copy
orig,
=i=0;i<3;i++)
new
new
copy;
int[3]{2,3,5};
int[3];
5:
for(int
copy[i]*=2;
4:
i=0;i<3;i++)
copy[i]=orig[i];
int[] 型の
変数orig
int[] 型の
変数copy
0
1
2
2
3
5
0
1
2
4
6
10
5
Array.Copy() メソッドを使う方法
(1:~7:は行番号)
1: int[] orig, copy;
2: orig = new int[3]{2,3,5};
3: copy = new int[3];
4: Array.Copy(orig, copy, orig.Length);
5: for(int i=0;i<3;i++) copy[i] *= 2;
6: foreach(int n in orig) Console.WriteLine(n);
7: foreach(int n in copy) Console.WriteLine(n);
6
コピーの際の注意点
3: copy = new int[3]; を忘れると,配列としての
容器が準備できていないのでコピーできない
コピー先配列の長さが短いと全部コピーできない
オリジナル(orig)の配列サイズが不明なときや変更
される可能性がある場合は,
copy = new int[3];
のように「数値」で直接書かずに
copy = new int[orig.Length];
のように作成したほうが変更の手間が少なくて便利
7
文字列の配列のときはどうなる?

1:
2:
3:
4:
5:
6:
7:
8:
(1:~8:は行番号)
String[] orig, copy;
orig = new String[3]{”守”,”破”,”離”};
copy = new String [3];
for(int i=0;i<3;i++) copy[i] = orig[i];
String temp;
temp = copy[1];
copy[1] = copy[2];
copy[2] = temp;
8
1: copy[2]
3:
String[]
copy
=copy[1];
orig,String[3];
copy;
4:
5:
6:
7:
8:
for(int
String
temp
copy[1]
=temp;
i=0;i<3;i++)
=new
copy[2];
temp;
copy[i]
= orig[i];
2:
orig=new
String[3]{“守”,
“破”,
“離”};
String[]
型の変数
orig
String
型の変数
temp
String[]
型の変数
copy
0
1
2
守
破
0
1
離
2
9
配列要素の初期化をfor文で行う
インデックスと同じ値を入れる
int[] a = new int[20];
for(int i=0;i<a.Length;i++) a[i] = i;
インデックスの3倍の数値を入れる
int[] a = new int[20];
for(int i=0;i<a.Length;i++) a[i] = i*3;
インデックスのn乗の数値を入れる
int[] a = new int[20];
for(int i=0;i<a.Length;i++) a[i] =
Math.Pow(a[i],n); //a[i]の累乗 ×a[i]^n
10
フィボナッチ数列の計算
★実例1★[13fib]
f[n] = f[n-1] + f[n-2]
の関係式が成り立つ数列
(ダヴィンチ・コードにもでてくる有名な数列)
double[] fib = new double[40];
fib[0] = 1;
fib[1] = 1;
for(int i=2 ; i < fib.Length ; i++)
fib[i] = fib[i-1] + fib[i-2];
(fibの中身) 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, ...11
練習問題9-1
[13fib] 黄金比
1 5
 1.6180339887...
2
フィボナッチ数列の隣り合う数の比は,徐々に
「黄金比」に近づくことが知られています.
★実例1★で求めたf[38]とf[39]を使って
f[39]/f[38]を計算し,上の黄金比と比べてみましょう.
★実例1★ では f[0] = 1, f[1] = 1 でスタートし
ましたが,他の数でやったらどうなるでしょうか?
数列をどこまで計算すれば上の小数点以下10桁
まで合った数値になりますか?
参考:ちなみに√は,Math.Sqrt(数値)で計算でき
ます(Square rootの略)

プログラムでは使わなくてもかけますが
12
平均値の計算
double sum=0, average;
double[] d = new double[10]
{7,6,5,4,6,8,3,5,9,6}; //数字は無意味
for(int i=0 ; i<d.Length ; i++){
sum += d[i];
}
average = sum / d.Length;
Console.WriteLine(“平均は {0}”,average);
13
配列のなかから一番大きい数を見つけ
る(ただし,Array.Sort() は使わずに)
★実例2★[14sortarray]
int max = 0;
int[] ary = new int[]{7,6,5,4,6,7,8,9,6};
for(int i=0; i < ary.Length ; i++){
if (max < ary[i]) max = ary[i];
}
Console.WriteLine(“最大の値は {0}”,max);
14
練習問題9-2 (少し難易度の高い問題)
配列の並び替え(ソート) [14sortarray]
intの配列 ary に入っている正の数値を,別
のintの配列sorted に大きい順に並び替えて
ください (★実例2★を参考にする)
ただし,Array.Sort()は使わず,aryで一番大
きい数値を探し, 1つずつ順番にコピーして
いってください
コピー済みの数値は0以下の数(任意)に置
き換えてください(配列 ary からデータを消し
てよい)
最後にsortedの中身を表示し確認すること 15
配列aryのコピー済み数値は消す
ary
ary
-1
7
6
5
4
6
-1
7 -1
8 -1
9
6
sorted
16
2次元配列
2次元配列変数の定義
int[,] matrix;
配列の作成
matrix = new int[2,2];
初期化
matrix[0,0] = 0;
matrix[0,1] = 1;
matrix[1,0] = 10;
matrix[1,1] = 11;
2つめの添字
↓ 列 ↓
1つ
めの
添字
0
1
行→
0
0
1
行→
1
10
11
0
1
10
11
17
2次元配列(九九の計算)
int[,] kuku = new int[10,10]; //都合上10にしておく
for(int i = 1; i <= 9 ; i++){
for(int j = 1 ; j <= 9 ; j++){
0 1 2 3 4..
kuku[ i , j ] = i * j;
0
}
1
1 2 3 4
}
2
2 4 6 8
3
4
5
:
★なぜ都合上10x10の配列に
したのだろうか?
9でも格納できるはずなのに...
3
4
5
6 9 12
8 12 16
10 15 20
18
行列計算★実例3(前半)★
double[,] a = new double[3, 2]{{1, 2}, {2, 1},
{0, 1}};
// 3行2列の行列
double[,] b = new double[2, 3]{{1, 2, 0},
{0, 1, 2}};
// 2行3列の行列
double[,] c = new double[3, 3]; // 3行3列の行列
// これから,行列を表す配列a,bの積を計算し,配列
cに入れていきたい(次ページ)
 1 2
 c00

 1 2 0 
   c10
 2 1   
 0 1  0 1 2  c


 20
c01 c02   1 4 4 
 

c11 c12    2 5 2 
c21 c22   0 1 2 
19
行列計算★実例3(後半)★
for(int i=0; i<a.GetLength(0); i++) {
// a.GetLength(0) は a の行数(=3)を表す
for(int j=0; j<b.GetLength(1); j++) {
// b.GetLength(1) は b の列数(=3)を表す
c[i, j] = 0;
for(int k=0; k<a.GetLength(1); k++) {
// a.GetLength(1) は a の列数(=2)を表す
c[i, j] += a[i, k] * b[k, j];
}
 1 2
 c00 c01 c02   1 4 4 

 1 2 0 
 

}
   c10 c11 c12    2 5 2 
 2 1   
 0 1  0 1 2  c
 

}
20


 20 c21 c22   0 1 2 
練習問題9-3
行列計算[15mulmatrix]
★実例3★のプログラムを入力し,
(1)行列a,bの作成と値の代入
(2)行列cの作成
(3)aとbの積をcに計算
の3つの処理がどこでどのように行われている
かを理解しなさい.
行列cの中身を画面に表示し,計算があって
いることを確認しなさい.

自分が確認しやすいように表示を工夫すること
数値を替えて,試してみよう
21
練習問題は,完成したらなるべく早く,
必ずコミットすること
(コミットメッセージは自由)
できれば授業中に!!
変数,条件分岐,ループ,配列
の4つに慣れてもらうためにしばらく足踏みし,
次回も配列,ループに関連した話題とする
22
今後の予定
( 9) 5/14 数値データと配列 / 多次元配列
(10) 5/16 文字列データと配列 / 可変長配列
(11) 5/21 関数
(12) 5/23 関数(メソッド) / オブジェクト指向
(13) 5/28 オブジェクト指向 / クラス定義

継承の概念は説明しない
(14) 5/30 GUIをもつプログラムの構成法

GUIは試験範囲外
(15) 6/4 最終試験 @K12
23