ご自宅に道具箱・工具箱はありますか?ごく一般的なご家庭であれば、げんのう、のこぎり、ドライバー、半田ごて。それから、これまでに購入したパーツの残り。そういったものを一緒くたに工具箱へ放りこんであるのではないでしょうか。私の工具箱はそんな感じです。工具といえばそこに入れてありますから、あちこち探すまでもありません。こんな具合で十分なのです。
しかし、大工さんともなればそうはいきません。工具は種類別、あるいは目的別に分類整理してあることでしょう。私のご近所の大工さんは、軽バンの後部を工具保管所にして、きれいに整理しておられます。工具は全て壁面に配置されています。釘やボルトといったパーツは、ずらりと積み重ねられたラベル付きの分類ボックスに収納されていました。道具や資材の分類・整理は、大工さんの仕事の基本であることは間違いありません。道具を取り出すのにまごついていては仕事になりませんものね。
集合の数学を、ものごとを明確に分類・整理し、性質を明らかに示すためのものととらえていきましょう。
今回は集合の数学で用いる記号とその意味、それを図示するとどうなるかを学びます。同時に、それらの数学的表現がJava言語でどう書き表されるかを見ていきましょう。
図30.1 整理・整頓は仕事の基本
集合と要素
集合の定義
集合に含まれる「もの」のことを要素 または元(げん) といいます。
図30.2 を集合の数学記号を用いて表現すると、次のように書くことが出来ます。式30.1 は「集合Aは要素a,b,c,d,eを持つ」と読みます。
図30.2 集合と要素の図示例 その1
式30.1はある集合Aにどんな要素が含まれているのかを列挙して定義しています。この方法の他に、実数値のように連続する値の集合を定義する場合のために次のような記法もあります。
式30.2 から式30.4 は実数のある範囲を示す集合を定義しています。このように定義すると、要素は無限に存在することになります。このような集合を無限集合 といいます。これに対して、式30.1のように要素の数が有限の場合の集合を有限集合 といいます。
Java言語で無限集合を表現する
無限集合をJava言語で表現するには、条件判断文や比較演算子を使うとよいでしょう。例えば、ある無限集合が式30.3 のように定義されていれば、次のコードのようにして任意の数値がその集合に含まれるか判定できます。
if ( 0 < x && x <= 5 ) System.out.println("集合X の要素です。");
配列で有限集合を表現する
では、有限集合はどうでしょう。Java言語で表現してみましょう。方法はいくつかありますが、ここでは最も基本的な、配列 を用いた方法を紹介します。
サンプルコード: HairetsuDeShugo.java
01: //サンプルコード
02: //集合を配列で表現する
03: //filename : HairetsuDeShugo.java
04:
05: class HairetsuDeShugo {
06: public static void main(String[] args) {
07: char A[] = {’a’,’b’,’c’,’d’,’e’};
08: for(int i=0; i<5; i++){
09: System.out.println("A["+i+"] = "+A[i]);
10: }
11: } // end of main
12: } // end of class HairetsuDeShugo
サンプルコード:HairetsuDeShugo.javaに配列の宣言と利用方法を示しました。配列の長所は大変シンプルなことです。しかし、実際にこのようなデータを取り扱う場合、配列は要素数が動的に変更できない[1] ため不便です。
ArrayListで有限集合を表現する
データの集合を取り扱う場合に便利な機能をあらかじめ装備したコレクション という仕組みがJava言語にあります。コレクションの中でもArrayListクラス は配列を拡張したものであるため、プログラミング入門者の方々には親しみやすいものだと思います。ただしArrayListに格納できるのは、プリミティブな型(intやfloat、booleanといった基本型のこと)ではなく、IntegerクラスやFloatクラスといったラッパークラスです。これはArrayListの便利さを用いるときのちょっとした制約と考えましょう。実際のソフトウエア開発では基本データ型よりも、データを取り扱うために便利な機能を付加したラッパークラスを使うことのほうが推奨されるからです[2] 。それと同じように、生の配列を使うよりは、コレクションクラスのArrayListを用いることが推奨されます。要素の総数を増減できますし、任意の位置に挿入、任意のデータを削除することも出来るからです[3] 。今回がいいチャンスですから、覚えておきましょう[4] 。
サンプルコード:ArrayListDeShugo.java
01: //サンプルコード
01: //ArrayList で集合を表現する
01: //filename : ArrayListDeShugo.java
04: import java.util.ArrayList;
05:
06: class ArrayListDeShugo {
07: public static void main(String[] args) {
08: ArrayList A = new ArrayList();
09: A.add("a");
10: A.add("b");
11: A.add("c");
12: A.add("d");
13: A.add("e");
14: for(int i=0;i<A.size();i++){
15: System.out.println("A.get("+i+") = " + (String)A.get(i));
16: }
17: } // end of main
18: } // end of class ArrayListDeShugo
集合を表現するためのその他の手段 MapとSet
Java言語でデータの集合を取り扱う場合、配列やArrayList以外の方法として、Map とSet があります。
今回は詳細は抜きにして、紹介のみにとどめます。配列やArrayListは、格納するデータを、そのデータに振られた通し番号で管理(格納された内容の取得や再格納)します。この番号を添字 といいます。それに対してMapは格納するデータに対して名前を付けます。この名前をキー といいます。名前は数値であってもよし、文字列であってもよし、場合に応じたものを選択できます。電話帳に掲載された電話番号が、その電話番号を持っている人の氏名と関係づけられているのと同じです。Setは単にデータを次々と保持します。データに関連づけられた添字やキーに当たるものはありません。データを特定するのは、そのデータの値そのものです。添字やキーが不要な場面で有効です。
問題:集合とJava言語に関する以下の問いに答えてください。
(1)穴埋め問題です。( あ)と(い)に当てはまる正しい数値を答えてください。
コード例:AnaumeShugo.java
01: class AnaumeShugo {
02: public static void main(String[] args) {
03: char a[] = {’a’,’b’,’c’,’d’,’e’};
04: for(int i=(あ);i<=(い);++i){
05: System.out.println("a["+i+"] = " + a[i]);
06: }
07: }// end of main
08: }// end of class AnaumeShugo
解説
(1)穴埋め問題です。( あ)と(い)に当てはまる正しい数値を答えてください。
この問題、( あ)のところにゼロ、( い)のところに4が入ります。迷うことなく正解された方は結構。しかし、意外と失敗するのがこの配列の添字。数を数えるのに1から始めるのが人情というもの。今そこにあるものをゼロと数えるのには、なかなか抵抗があります。コンピュータのハードウエアの学習などをされた方にとっては、「 0番地から始まるメモリのアドレス」といったことで慣れ親しんでいるものですが、ごく一般的な理系・文系の学習をされてきた方々には、最初受け入れがたいと思います。かくいう私も、よくこのミス(配列のカウントは0から[5] )でバグを入れたりします。ものの数は1から数えるというクセがでてしまいます。そして、n個ある配列の最後の添え字はnだ、ってね。正しくはn-1までなのに。自戒の念も込めて、ここに問題として紹介した次第。
[5] 他言語や設定によっては、配列の先頭要素の添字を1とするものがあります。例えばVBでは宣言時の添字に5を用いると、添字は0から5まで使えます。要素数が一つ多く確保されます。賛否あるところでしょうが、私は重宝しています。
今回はここまで
今回は、集合の数学での集合の定義の方法、そしてJava言語での集合の取り扱い方を紹介しました。
今回のまとめ
集合の定義は、有限個数の要素をいちいち列挙する方法と、連続な範囲を指定する方法、集合に含まれるものの性質を言葉で表現する方法などがあります。
Java言語で集合を表現する最も基本的な方法は配列とArrayListです。