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