[小西ホームページ]   [目次・索引]   [前の授業]   [次の授業]

情報処理技法(Javaプログラミング)I 第9回

目次
索引

データの入出力(4)

エスケープ・シーケンス

ターミナルに"OK"と出力するには、

System.out.println("OK");

と書きました。 では、ダブルクオート(")も出力するにはどうすればよいでしょうか。 正解は、

System.out.println("\"OK\"");

です。

文字列 \" がダブルクオートの代りになるように、直接扱いにくい文字の代りとなる文字列を、 エスケープ・シーケンス escape sequence )とよびます。 Javaのエスケープ・シーケンスは以下の通りです。

エスケープ・シーケンス
\b バックスペース
\t タブ
\n 改行
\f フォームフィード
\r 復帰
\" ダブルクオート
\' シングルクオート
\\ バックスラッシュ

注意: 記号 \ は、環境によってバックスラッシュになったり円記号になったりします。 エスケープ・シーケンスを使うとき、Windowsでは、円記号キーを押して、円記号を入力してください。 Macでは、Optionキーを押しながら円記号キーを押して、バックスラッシュを入力してください。

エスケープ・シーケンスの「タブ」とは、一定のきざみ(たいていは8文字単位)の位置まで設けられる間隔のことです。 データを表のような形式で出力するときに役に立ちます。

TabTest.java
class TabTest { // タブのテスト
    public static void main (String[] args) {
        System.out.println("1\tone");
        System.out.println("10\tten");
        System.out.println("100\thundred");
        System.out.println("1000\tthousand");
    }
}
ターミナル
PS ...\Desktop\java1>  & ... 'TabTest'
1       one
10      ten
100     hundred
1000    thousand
PS ...\Desktop\java1>

配列(2)

配列要素の挿入と削除

前回、配列は、一度用意すると要素数は変えられないと言いました。 要素数を5個に決めたら、ずっと5個のままです。 しかし、配列に要素を挿入したり、配列から要素を削除したい場合もあるでしょう。 この問題を解決するには、次のような方法が考えられます。

ここでは、大きな配列を用意する方法について説明します。 配列をコピーする方法については、次の小節で説明します。

大きな配列の最初の部分を使うには、配列の要素数とは別に、データの個数を覚えておきます。 例えば、データの個数を変数 count で表します。 そして、for文などで、配列の要素数 a . length の代わりに、 count を使います。

次のプログラムでは、配列の要素数は10, データの個数は5として、すべてのデータを出力しています。

ArrayStack.java
class ArrayStack { // 配列によるスタック
    public static void main (String[] args) {
        int[] a = {10, 11, 12, 13, 14, 0, 0, 0, 0, 0}; // 要素数は10
        int count = 5; // データの個数は5
        for (int i = 0; i < count; i++) { // データの個数回繰り返す
            System.out.println("a[" + i + "] = " + a[i]);
        }
    }
}
ターミナル
PS ...\Desktop\java1>  & ... 'ArrayStack'
a[0] = 10
a[1] = 11
a[2] = 12
a[3] = 13
a[4] = 14
PS ...\Desktop\java1>

この配列にデータ15を挿入するには、 a [ count ]にデータ15を格納し、 count を1増加させます。 つまり、

a = {10, 11, 12, 13, 14, 0, 0, 0, 0, 0}, count = 5.

a = {10, 11, 12, 13, 14, 15, 0, 0, 0, 0}, count = 6.

に変更します。

ArrayPush.java
class ArrayPush { // 配列へのプッシュ
    public static void main (String[] args) {
        int[] a = {10, 11, 12, 13, 14, 0, 0, 0, 0, 0};
        int count = 5;
        a[count] = 15; // データを挿入
        count++; // データの個数を1増加
        for (int i = 0; i < count; i++) {
            System.out.println("a[" + i + "] = " + a[i]);
        }
    }
}
ターミナル
PS ...\Desktop\java1>  & ... 'ArrayPush'
a[0] = 10
a[1] = 11
a[2] = 12
a[3] = 13
a[4] = 14
a[5] = 15
PS ...\Desktop\java1>

元の配列から最後のデータ14を削除するには、 count を1減少させます。 つまり、

a = {10, 11, 12, 13, 14, 0, 0, 0, 0, 0}, count = 5.

a = {10, 11, 12, 13, 0, 0, 0, 0, 0, 0}, count = 4.

に変更します。 なお、 a [ count ]を0にしていますが、本当は必要ありません。

ArrayPop.java
class ArrayPop { // 配列からのポップ
    public static void main (String[] args) {
        int[] a = {10, 11, 12, 13, 14, 0, 0, 0, 0, 0};
        int count = 5;
        count--; // データの個数を1減少
        a[count] = 0; // やらなくてもよい
        for (int i = 0; i < count; i++) {
            System.out.println("a[" + i + "] = " + a[i]);
        }
    }
}
ターミナル
PS ...\Desktop\java1>  & ... 'ArrayPop'
a[0] = 10
a[1] = 11
a[2] = 12
a[3] = 13
PS ...\Desktop\java1>

配列のコピー

整数(int型)の変数 x から変数 y にコピーするには、代入文 y = x; でできます。 しかし、配列 a の要素から配列 b の要素にコピーするには、 b = a; ではできません。

b[0] = a[0];
b[1] = a[1];
b[2] = a[2];
...

のように、一つ一つ配列要素をコピーする必要があります。

配列のコピー
配列のコピー

次のプログラムは、配列 a の要素から配列 b の要素にコピーし、 b の要素を出力するものです。

ArrayCopy.java
class ArrayCopy { // 配列のコピー
    public static void main (String[] args) {
        int[] a = {10, 11, 12, 13, 14};
        int[] b = new int[a.length]; // 同じ要素数の配列を生成
        for (int i = 0; i < a.length; i++) {
            b[i] = a[i]; // 要素ごとにコピー
        }
        for (int i = 0; i < b.length; i++) {
            System.out.println("b[" + i + "] = " + b[i]);
        }
    }
}
ターミナル
PS ...\Desktop\java1>  & ... 'ArrayCopy'
b[0] = 10
b[1] = 11
b[2] = 12
b[3] = 13
b[4] = 14
PS ...\Desktop\java1>

4行目で、配列 a と同じ要素数の配列 b を宣言し、生成します。 5行目から7行目のfor文でコピーが行われます。 繰り返しの回数として a . length と書いていますが、配列 a b の要素数は同じなので、 b . length と書いてもよいです。

配列をコピーする方法で、この配列にデータ15を挿入するには、まず、要素数が1個多い配列を新たに生成します。 そして、元の配列から新しい配列にコピーして、新しい配列の最後にデータ15を格納します。 つまり、

a = {10, 11, 12, 13, 14}

から

b = {10, 11, 12, 13, 14, 15}

を作成します。

ArrayInsert.java
class ArrayInsert { // 配列への挿入
    public static void main (String[] args) {
        int[] a = {10, 11, 12, 13, 14};
        int[] b = new int[a.length + 1]; // 1個多く生成
        for (int i = 0; i < a.length; i++) { // すべてコピー
            b[i] = a[i];
        }
        b[a.length] = 15; // データを挿入
        for (int i = 0; i < b.length; i++) {
            System.out.println("b[" + i + "] = " + b[i]);
        }
    }
}
ターミナル
PS ...\Desktop\java1>  & ... 'ArrayInsert'
b[0] = 10
b[1] = 11
b[2] = 12
b[3] = 13
b[4] = 14
b[5] = 15
PS ...\Desktop\java1>

配列をコピーする方法で、元の配列から最後のデータ14を削除するには、まず、要素数が1個少ない配列を新たに生成します。 そして、元の配列から新しい配列にコピーします。 ただし、元の配列の最後の要素はコピーしません。 つまり、

a = {10, 11, 12, 13, 14}

から

b = {10, 11, 12, 13}

を作成します。

ArrayDelete.java
class ArrayDelete { // 配列からの削除
    public static void main (String[] args) {
        int[] a = {10, 11, 12, 13, 14};
        int[] b = new int[a.length - 1]; // 1個少なく生成
        for (int i = 0; i < a.length - 1; i++) { // 最後以外をコピー
            b[i] = a[i];
        }
        for (int i = 0; i < b.length; i++) {
            System.out.println("b[" + i + "] = " + b[i]);
        }
    }
}
ターミナル
PS ...\Desktop\java1>  & ... 'ArrayDelete'
b[0] = 10
b[1] = 11
b[2] = 12
b[3] = 13
PS ...\Desktop\java1>

配列への入力

ここでは、配列の初期化ではなく、プログラムの実行時に、配列にデータを入力する方法を考えてみます。 この場合、データの個数があらかじめ分かっているかどうかで、配列の使い方が変わります。 あらかじめ分かっていない場合は、まず、大きめの配列を用意します。 そして、 count などの変数でデータの個数を数えながら、入力されたデータを配列に挿入していきます。 データの終わりを判定するために、何か特別な値(例えば0)が入力されたら入力終了と見なします。

ArrayInput.java
import java.util.Scanner;

class ArrayInput { // 配列への入力
    public static void main (String[] args) {
        Scanner stdIn = new Scanner(System.in);
        int[] a = new int[10]; // データは10個まで
        int input, count = 0; // 最初は0個
        System.out.println("データは" + a.length + "個までです。");
        System.out.println("終了は0を入力してください。");
        while (true) { // 無限ループ
            System.out.print("a[" + count + "] = ? ");
            input = stdIn.nextInt(); // 入力
            if (input == 0) { // 0なら終了
                break;
            }
            a[count] = input; // 挿入
            count++; // 1増加
        }
        for (int i = 0; i < count; i++) {
            System.out.println("a[" + i + "] = " + a[i]);
        }
    }
}
ターミナル
PS ...\Desktop\java1>  & ... 'ArrayInput'
データは10個までです。
終了は0を入力してください。
a[0] = ? 10
a[1] = ? 11
a[2] = ? 12
a[3] = ? 13
a[4] = ? 14
a[5] = ? 0
a[0] = 10
a[1] = 11
a[2] = 12
a[3] = 13
a[4] = 14
PS ...\Desktop\java1>

あらかじめデータの個数が分かっている場合は、まず、データの個数を入力させます。 そして、その要素数の配列を生成し、配列要素を一つずつ入力させます。 この場合は、終了を表す特別な値を使わなくてもよいです。

ArrayInput2.java
import java.util.Scanner;

class ArrayInput2 { // 配列への入力2
    public static void main (String[] args) {
        Scanner stdIn = new Scanner(System.in);
        int input;
        System.out.print("データの個数を入力してください: ");
        input = stdIn.nextInt(); // 入力
        int[] a = new int[input]; // 個数が分かってから配列を生成
        for (int i = 0; i < a.length; i++) { // データの個数回繰り返す
            System.out.print("a[" + i + "] = ? ");
            input = stdIn.nextInt(); // 入力
            a[i] = input; // 挿入
        }
        for (int i = 0; i < a.length; i++) {
            System.out.println("a[" + i + "] = " + a[i]);
        }
    }
}
ターミナル
PS ...\Desktop\java1>  & ... 'ArrayInput2'
データの個数を入力してください: 5
a[0] = ? 10
a[1] = ? 11
a[2] = ? 12
a[3] = ? 13
a[4] = ? 14
a[0] = 10
a[1] = 11
a[2] = 12
a[3] = 13
a[4] = 14
PS ...\Desktop\java1>

並列配列

次のような表の形のデータは、データをまとめるときによく使われます。

表の形のデータ
No. 0 1 2 3 4
項目A 10 11 12 13 14
項目B 20 21 22 23 24
項目C 30 31 32 33 34

このような表の形のデータは、配列をいくつか用意し、添字を使って配列要素を結び付けるとうまく処理できます。 このように使われる配列を 並列配列 parallel array )とよびます。

この場合なら、項目Aを配列 a に格納し、項目Bを配列 b に格納し、項目Cを配列 c に格納します。 すると、0番目のデータは、項目Aが a [0], 項目Bが b [0], 項目Cが c [0] となります。 1番目のデータは、項目Aが a [1], 項目Bが b [1], 項目Cが c [1] などとなるわけです。

プログラムでは、タブ \t を使って、表に近い形でこのデータを出力しています。

ParallelArrays.java
class ParallelArrays { // 並列配列
    public static void main (String[] args) {
        int[] a = {10, 11, 12, 13, 14}; // 項目A
        int[] b = {20, 21, 22, 23, 24}; // 項目B
        int[] c = {30, 31, 32, 33, 34}; // 項目C
        System.out.println("No.\t項目A\t項目B\t項目C");
        for (int i = 0; i < a.length; i++) {
            System.out.print(i + "\t"); // タブ
            System.out.print(a[i] + "\t"); // タブ
            System.out.print(b[i] + "\t"); // タブ
            System.out.println(c[i]); // 改行
        }
    }
}
ターミナル
PS ...\Desktop\java1>  & ... 'ParallelArrays'
No.     項目A   項目B   項目C
0       10      20      30
1       11      21      31
2       12      22      32
3       13      23      33
4       14      24      34
PS ...\Desktop\java1>

並列配列の例として、以下の単価と数量の合計金額を計算します。

単価と数量
No. 0 1 2 3 4
単価 200 500 400 100 600
数量 3 1 2 7 1

まず、配列 unitPrices quantities を初期化して、 i 番目の単価が unitPrices [ i ], 数量が quantities [ i ] になるようにします。 i 番目の金額 price は、 unitPrices [ i ] * quantities [ i ] で求められます。 合計金額を計算するには、この price の値を totalPrice に足していきます。

プログラムは次の通りです。

TotalPrice.java
class TotalPrice { // 合計金額
    public static void main (String[] args) {
        int price, totalPrice = 0;
        int[] unitPrices = {200, 500, 400, 100, 600}; // 単価
        int[] quantities = {3, 1, 2, 7, 1}; // 数量
        System.out.println("No.\t単価\t数量\t金額");
        for (int i = 0; i < unitPrices.length; i++) {
            price = unitPrices[i] * quantities[i]; // 金額の計算
            totalPrice += price; // 合計の計算
            System.out.print(i + "\t");
            System.out.print(unitPrices[i] + "\t");
            System.out.print(quantities[i] + "\t");
            System.out.println(price);
        }
        System.out.println("合計\t\t\t" + totalPrice);
    }
}
ターミナル
PS ...\Desktop\java1>  & ... 'TotalPrice'
No.     単価    数量    金額
0       200     3       600
1       500     1       500
2       400     2       800
3       100     7       700
4       600     1       600
合計                    3200
PS ...\Desktop\java1>

演習9

ある小学校では、児童数が次の通りであるとします。

ある小学校の児童数
学年 1年 2年 3年 4年 5年 6年
男子 50 54 59 58 57 51
女子 53 55 56 52 50 50

このデータを配列 boys girls に格納して、学年ごとの児童数と全児童数を計算するプログラムを作成してください。

ヒント: 配列に格納するときは、「0年生」が0人いることにすれば、うまくいきます。 for文も、0から始める必要はありません。

ElementarySchool.java
class ElementarySchool {
    public static void main (String[] args) {
        int[] boys = {0, 50, 54, 59, 58, 57, 51};
        int[] girls = {0, 53, 55, 56, 52, 50, 50};
        
        
        
    }
}
ターミナル
PS ...\Desktop\java1>  & ... 'ElementarySchool'
学年    男子    女子    合計
1年     50      53      103
2年     54      55      109
3年     59      56      115
4年     58      52      110
5年     57      50      107
6年     51      50      101
合計                    645
PS ...\Desktop\java1>

余力のある人は、全体の男子児童数と女子児童数も計算してください。

ターミナル
PS ...\Desktop\java1>  & ... 'ElementarySchool2'
学年    男子    女子    合計
1年     50      53      103
2年     54      55      109
3年     59      56      115
4年     58      52      110
5年     57      50      107
6年     51      50      101
合計    329     316     645
PS ...\Desktop\java1>

レポート課題

今日の演習9の答案(Javaプログラム)をメールで提出してください。 差出人は大学発行のメール・アドレス(学生番号@cis.twcu.ac.jp)とし、宛先はkonishi@cis.twcu.ac.jpとします。 メールの本文には、学生番号、氏名、科目名、授業日(6月6日)を明記してください。


参考文献


[小西ホームページ]   [目次・索引]   [前の授業]   [次の授業]

2025年6月6日更新
小西 善二郎 <konishi@cis.twcu.ac.jp>
Copyright (C) 2025 Zenjiro Konishi. All rights reserved.