import java.io.*; class Test8{ public static void main(String[] args) throws IOException{ // 入力をするためには,System.inからBufferedReaderを作らなくてはいけない BufferedReader d=new BufferedReader(new InputStreamReader(System.in)); System.out.print("月(1-12)を入力して下さい "); // 入力をおこなう前に, バッファリングされていた出力を出してします System.out.flush(); String s=d.readLine(); // 文字列をint型に変換する. int month=Integer.parseInt(s); // 入力した月が1より小さい時,12より大きい時は次の if 文を実行します if(month<1 || month>12) System.out.println(month+"月はありません"); if(month==1) System.out.println("1月は January です. "); if(month==2) System.out.println("2月は Febrary です. "); if(month==3) System.out.println("3月は March です. "); if(month==4) System.out.println("4月は April です. "); if(month==5) System.out.println("5月は May です. "); if(month==6) System.out.println("6月は June です. "); if(month==7) System.out.println("7月は July です. "); if(month==8) System.out.println("8月は August です. "); if(month==9) System.out.println("9月は Sepember です. "); if(month==10) System.out.println("10月は October です. "); if(month==11) System.out.println("11月は November です. "); if(month==12) System.out.println("12月は December です. "); } }ここで,
if(month<1 || month>12) System.out.println(month+"月はありません");の「||」は複数の条件式の論理和をあらわす.(A||B)は「AまたはB」という意 味で,すなわち条件Aか条件Bのどちらかが真になると真になる.この条件式は 「monthの値が1より小さいとき,またはmonthの値が12より大きいとき」とい う意味である.
この逆が「&&」で論理積となる.(A&&B)は「AかつB」という意味で,条 件Aか条件Bの両方が真のときのみ真になる.
これで動くことは動くがあまりすっきりしないプログラムである. これを,
import java.io.*; class Test9{ public static void main(String[] args) throws IOException{ // 入力をするためには,System.inからBufferedReaderを作らなくてはいけない BufferedReader d=new BufferedReader(new InputStreamReader(System.in)); System.out.print("月(1-12)を入力して下さい "); // 入力をおこなう前に, バッファリングされていた出力を出してします System.out.flush(); String s=d.readLine(); // 文字列をint型に変換する. int month=Integer.parseInt(s); if(month<1 || month>12) System.out.println(month+"月はありません"); else { String mname=""; if(month==1) mname="January"; else if(month==2) mname="Febrary"; else if(month==3) mname="March"; else if(month==4) mname="April"; else if(month==5) mname="May"; else if(month==6) mname="June"; else if(month==7) mname="July"; else if(month==8) mname="August"; else if(month==9) mname="September"; else if(month==10) mname="October"; else if(month==11) mname="November"; else if(month==12) mname="December"; System.out.println(month+"月は "+mname+" です. "); } } }これで, すっきりとしたことはすっきりとしたが, else ifの繰り返しはまだ まだうっとおしい. 前のページのプログラムの
else if(month==5) mname="May"; else if(month==6) mname="June";のような, 整数の値によって, 変数の値が変わるといったパターンを簡潔にプ ログラムするために, 多くのプログラム言語では配列が用意されている.
import java.io.*; class Test10{ public static void main(String[] args) throws IOException{ // 入力をするためには,System.inからBufferedReaderを作らなくてはいけない BufferedReader d=new BufferedReader(new InputStreamReader(System.in)); System.out.print("月(1-12)を入力して下さい "); // 入力をおこなう前に, バッファリングされていた出力を出してします System.out.flush(); String s=d.readLine(); // 文字列をint型に変換する. int month=Integer.parseInt(s); // 文字列の配列型の変数 mnames を宣言し,{}で囲まれた初期値を入れる. String mnames[]={"January","Febrary","March","April","May","June", "July","August","September","October", "November","December"}; if(1<=month && month<=12) System.out.println(month+"月は "+mnames[month-1]+" です. "); else System.out.println(month+"月はありません"); } }上のように
String mnames[]と書くと文字列の配列を入れるmnames という名前の変数を宣言したことにな る. '='の右側の内容で配列の内容を初期化している. 配列の要素数(大きさ)は この例では12である.
配列型の変数の参照は 「変数名[添字]」のようにしておこなう. 添字は1で はなく0から始まることに注意しよう. 添字はint型でなくてはいけない.
float型,double型の変数を添字に使うのはキャスト演算子「(型名)式」でint 型に変換すれば可能だが,そうする必要がある場合の多くはその変数は本来 int型にすべきである.特に,ループの繰り返しを判定する変数などを, float, doubleにすると誤差により,ループの回数が意図しない回数になる可 能性がある.この場合は大(double)は小(int)を兼ねない.
注意)
String mnames[]={"January","Febrary","March","April","May","June", "July","August","September","October", "November","December"};を
String mnames[]; mnames={"January","Febrary","March","April","May","June", "July","August","September","October", "November","December"};のように, 宣言と代入に分けて書くことはできない.
class Test11{ public static void main(String[] args{ int n=1000,i,k; int p[]=new int[n+1]; for(i=2; i<=n; i++) p[i]=1; // i++はi=i+1と同じ意味 for(i=2; i<=n; i++) if(p[i]==1){ System.out.print(i+" "); for(k=2; i*k<=n; k++) p[i*k]=0; } } }このプログラムでは p という配列が使われている. iが素数の可能性がある 時はp[i]が1, 合成数の時はp[i]が0になるように計算していく. 配列の宣言と 作成は,int p[]=new int[n+1];の部分である. これは,int p[]; p=new int[n+1];という2つの文に分けて書いても良い(続けて書かなくても良い). newは配列や オブジェクトの生成を表す予約語で, 次のintは要素の型を示す. [n+1]は作成 する配列の大きさ(要素数)が n+1 であることを示す. 配列の大きさを宣言時 に決定しなくてもよいのは, Javaの特徴の1つである.
上のプログラムで素数が求まる原理が分かりにくいかもしれない. はいぱーワークブック「プログラミング」でも 配列によるチェックのページでほとんど同じプログラムを扱っているので, 分からない人はそちらの説明を見て欲しい. 注)上のプログラムでは int の配列を使っているが, よりJavaらしく書くなら boolean(真偽値を表す型)の配列を使って
class Test12{ public static void main(String[] args){ int n=1000,i,k; boolean p[]=new boolean[n+1]; for(i=2; i<p.length; i++) p[i]=true; for(i=2; i<p.length; i++) if(p[i]){ System.out.print(i+" "); for(k=2; i*k<=n; k++) p[i*k]=false; } } }のように書く. なお配列型の変数に .lengthをつけて p.lengthのようにする と, その配列の要素数を返す.
これまで, 呪文のように打ち込んできたpublic static void main(String[] args){の「String[] args」の部分は, 実は文字列の配列である引数(「ひきすう」と 読む. 外から値を渡すためのものだが, 中から見ると初期化済の変数と思って 良い)だとわかる. 実は, java を起動する時にjava プログラム名 a1 a2 .. anのように後ろに空白で区切って文字列をいくつか書くとargs[0] <- "a1" args[1] <- "a2" .. args[n-1] <- "an"のように配列argsの中に渡すことができる. この機能を利用して, 次の プログラムを書いてみる.class Test13{ public static void main(String[] args){ for(int i=args.length-1;i>0;i--) System.out.println(args[0]+args[i]); } }このプログラムをコンパイルして,java Test13 I can read this file.と実行すると,ktanaka@ux019> java Test13 I can read this file. Ifile. Ithis Iread Icanという出力が得られる.
配列が出てきたので,前回の課題の解答例(2)が理解できるはずなので説明する.class Kadai1018{ public static void main(String[] args){ // 10001のサイズの配列を取ると 0-10000までの添字(index)が使える. // checkの配列は3乗の和でそれまで何通りの表わし方が見つかってい // るかを記録する int check[]=new int[10000+1]; // 配列の要素をすべて0にする.Java言語では言語仕様で // intの配列の初期値は0と決まっているので,for文全体は不要 for(int i=1;i<=10000;i++){ // ^ のように,for文内だけで使う変数はその場で宣言することができる // この講義のサンプルではこのようにしないが,このような書き方を推奨 // している本もある. check[i]=0; } // ペアの大きい方のiの範囲は1<=i<=10000(本当は9999で良い?) for(int i=1;(i*i*i)<=10000;i++){ for(int j=1;j<=i;j++){ int k=(i*i*i)+(j*j*j); // 3乗和 k が10000以下なら,check[k]を1増やす. if(k<=10000){ check[k]++; } } } // 1から10000までで,2回以上3乗和で表わされた回数が2以上のものを表示する. for(int i=1;i<=10000;i++){ if (check[i]>=2){ System.out.println(i); } } } }
次に進む