プログラミング基礎I(再)

山元進
配列とは
 配列の宣言
 配列要素の確保
 添字
 配列の初期化
 配列変数
 配列の長さ
 他次元配列



大量のデータに番号をつけ、
まとめて取り扱うしくみ


例:50人の受験者の成績を集計(和をとる)
配列がない場合


配列を使う場合 (test[ ] が配列と呼ばれるもの)



int sum=test1+test2+ …(+test50 まで繰り返す)
int sum=0;
for(int i=0; i<50 ; i++ ) sum += test[i];
同じ型の値を複数まとめて記憶する

配列として使う識別子を決める


配列として扱うデータの数を決める


例えば, int[] test; // 配列変数 test を宣言
例えば 5 個とする
上で決めた数だけのデータを記憶するための
記憶領域を確保する
test = new int[5]; // 5: 配列のサイズ (長さ)
 これで test[0], test[1], test[2], test[3], test[4]
の5個のデータをまとめて扱える
 [ ]内は整数型で、添字と呼ぶ

配列の長さ = 配列に含まれる要素の数
 配列の長さ -1 = 最大の添字


添字は 0 から始まる
配列変数名[添字] が通常の変数に相当
 配列に含まれるデータを記憶する記憶領域を
確保した後でないと、データを書き込んだり読
み出したりすることができない。


test = new int[5]; // 記憶領域確保

添字で要素を指定し 、値を代入する
test[0] = 80; //
 test[1] = 60; // test[0] とは違う場所に対応

class Sample1
{
public static void main(String[] args)
{
int[] test; // この例では int test[]; も可
test = new int[5]; // 要素分の記憶領域確保
test[0] = 80; test[1] = 60;
test[2] = 22; test[3] = 50; test[4] = 75;
for(int i=0; i<5; i++){
System.out.println((i+1)
+ "番目の人の点数は"+ test[i] + "です。");
} // 繰り返し文を使ってまとめて処理
}
}

添字 < 配列の長さ
この限度を超えるとエラーとなる
 例えば Sample1.java で



test[5] = 100;
などとやるとエラーになる
import java.io.*;
class Sample2
{
public static void main(String[] args) throws IOException
{
System.out.println("テストの受験者数を入力してください。");
BufferedReader br = new BufferedReader(
new InputStreamReader(System.in));
String str = br.readLine(); // キーボードからの入力
int num = Integer.parseInt(str); // 整数に変換
int test[];
test = new int[num]; // 要素分のメモリ確保
System.out.println("人数分の点数を入力してください。");
for(int i=0; i<num; i++){
str = br.readLine();
test[i] = Integer.parseInt(str); // tmp は不要
}
for(int i=0; i<num; i++){
System.out.println((i+1)
+"番目の人の点数は"+ test[i] + "です。");
}
}
}

配列の宣言と記憶領域確保を同時に


int [] test = new int [5];
配列宣言・初期化、記憶領域確保を同時に

int[] test = {80,60,22,50,75};
class Sample3
{
public static void main(String[] args)
{
int[] test = new int[5]; // 宣言とメモリ確保同時
test[0] = 80;
test[1] = 60;
test[2] = 22;
test[3] = 50;
test[4] = 75;
for(int i=0; i<5; i++){
System.out.println((i+1)
+"番目の人の点数は"+ test[i] + "です。");
}
}
}
class Sample4
{
public static void main(String[] args)
{
int[] test = {80,60,22,50,75};
for(int i=0; i<5; i++){
System.out.println((i+1)
+"番目の人の点数は"+ test[i] + "です。");
// {80,60,22,50,75} で new (記憶領域確保) と
// 初期化を同時に行った
}
}
}

new で記憶領域を確保
int[] test1 = new int[5];
int[] test2 = test1;
test2 に対して独自の記憶領域は確保されない
test2[2]=5;
System.out.println(test1[2]);
5 と出力される
 上の例では、test2 は test1 の別名で、実態は
test1 と同じ
class Sample6
{
public static void main(String[] args)
{
int[] test1 = {80,60,22};
System.out.println("test1を宣言しました。");
System.out.println("配列要素を確保しました。");
int[] test2 = test1;
System.out.println("test2を宣言しました。");
System.out.println("test2にtest1を代入しました。");
for(int i=0; i<3; i++){
System.out.println("test1が指す"+(i+1)
+"番目の人の点数は"+test1[i]+"です。");
}
for(int i=0; i<3; i++){
System.out.println("test2が指す"+(i+1)
+"番目の人の点数は"+test2[i]+"です。");
}
test1[2]=100;
System.out.println(
"test1が指す3番目の人の点数を変更します。");
for(int i=0; i<3; i++){
System.out.println("test1が指す"+(i+1)
+"番目の人の点数は"+test1[i]+"です。");
}
for(int i=0; i<3; i++){
System.out.println("test2が指す"+(i+1)
+"番目の人の点数は"+test2[i]+"です。");
} // test1 も test2 も同じ記憶領域を指すので、
// test2[2] も 100 になっている
}
}

配列の長さを知る
配列名.length = 配列の長さ
例 test.length


配列に対する操作を繰り返し文でおこなうとき

配列の終端は 配列名.length にするとよい
class Sample8
{
public static void main(String[] args)
{
int[] test = {80,60,22,50,75};
for(int i=0; i<test.length; i++){
System.out.println((i+1)+
"番目の人の点数は"+test[i]+"です。");
}
System.out.println(
"テストの受験者は"+test.length+"です。");
}
}
import java.io.*;
class Sample9
{
public static void main(String[] args) throws IOException
{
BufferedReader br = new BufferedReader(
new InputStreamReader(System.in));
int[] test = new int[5];
System.out.println(test.length+"人の点数を入力してください");
for(int i=0; i<test.length; i++){
String str = br.readLine();
test[i] = Integer.parseInt(str);
}
for(int i=0; i<test.length; i++) // 並べ替え開始
for(int j=i+1; j<test.length; j++) // i 以降で最大値探索
if(test[j] > test[i]){ // test[i] より大きな値あれば
int tmp = test[j]; // test[i] と test[j] の中身を交換
test[j] = test[i];
test[i] = tmp;
}
for(int i=0; i<test.length; i++)
System.out.println((i+1)+"番目の人の点数は"+test[i]+"です。");
}
}

int[] test={4,2,1,3}; を初期値とする
i=0
i=1
i=2
i=3
j=0
なし
(j=i+1 から)
なし
(j=i+1 から)
なし
(j=i+1 から)
なし
(j=i+1 から)
j=1
test[1]<test[0]
{4,2,1,3}
なし
(j=i+1 から)
なし
(j=i+1 から)
なし
(j=i+1 から)
j=2
test[2]<test[0]
{4,2,1,3}
test[2]<test[1]
{4,2,1,3}
なし
(j=i+1 から)
なし
(j=i+1 から)
j=3
test[3]<test[0]
{4,2,1,3}
test[3]>test[1]
{4,3,1,2}
test[3]>test[2]
{4,3,1,2}
なし
(j=i+1 から)

2次元配列の例
int[][] test;
test = new int[2][5]; // 2科目 5人
class Sample10
{
public static void main(String[] args)
{
int[][] test;
test = new int[2][5];
test[0][0]=80; test[1][0]=90;
test[0][1]=60; test[1][1]=55;
test[0][2]=22; test[1][2]=68;
test[0][3]=50; test[1][3]=72;
test[0][4]=75; test[1][4]=58;
for(int i=0; i<5; i++){
System.out.println((i+1)+
"番目の人の国語の点数は"+test[0][i]+"です。");
System.out.println((i+1)+
"番目の人の算数の点数は"+test[1][i]+"です。");
}
}
}

一次元のときと同様。ただし、{ } がネスト
int[][] test = { {80,60,22,50,75},
{90,55,68,72,58} };

1番目の添字ごとに違う長さでもよい
(いびつな配列も作れる)
int[][] test = { {80,60,22,50}, // 長さ 4
{90,55,68,72}, // 長さ 4
{33,75,63} }; // 長さ 3 で前と違う
class Sample11
{
public static void main(String[] args)
{
int[][] test = {
{80,60,22,50}, {90,55,68,72}, {33,75,63}
};
for(int i=0; i<test.length; i++){ //length=3
System.out.println((i+1)+
"番目の配列の長さは"+test[i].length+"です。");
}
}
}
配列を宣言し、new演算子で配列要素確保
 配列変数を使って、配列要素に値を代入
 { }内に値を並べて初期化した配列を作成
 配列変数名に.lengthをつけて、要素数
 配列変数を別の配列変数に代入できる
 他次元配列を作成して使うことができる


次のプログラムを見て後の問いに答えよ
import java.io.*;
class Report1
{
public static void main(String args[]) throws IOException
{
System.out.println("正の整数を入力してください。");
BufferedReader br = new BufferedReader(new
InputStreamReader(System.in));
String str = br.readLine(); // キーボードからの入力
int num = Integer.parseInt(str); // 整数に変換
if(num > 0){
int num1 = num;
int keta = 1;
while( (num1 /= 10) > 0) keta++;
System.out.println("入力された"+num+"は"+keta+"桁の数です。");
}else{
System.out.println("正の整数を入力してください。");
}
}
}

自分の学籍番号の下3ケタを入力したとして、
while 文の ( ) 内を評価した後の、各変数の
値を答え、このプログラムの働きを TA に説明
せよ
1回目
2回目
3回目
4回目
num1
keta
このプログラムを書き換え、入力した整数値の
下からkケタ目を n[k-1] に格納するようにせよ
 さらに、入力した数値の各ケタの数の総和、総
乗を出力するようにせよ

Sample9.java (改) で入力する数値を4つに
するには、どうすればよいか答えよ
 Sample9.java (改) で数が大きい順に並べ
替えられる理由を、TA に説明せよ(TAがサ
ンプル入力として4つの数を決め、その入力
に対する動作を説明できれば十分とする)
 並べ替えの順序を、小さい順に変更するには、
Sample9.java (改) のどこをどうすれば良い
か答えよ


変更したプログラムは Report2.java として提出

※
Sample10.javaのプログラムを配列の宣言と初
期化を同時に行う形に書き直せ
今日は、演習問題1~3 全てを提出すること!!