目次 | 索引 |
---|---|
この授業の内容は、Javaのプログラムを作成することです。 そもそも、プログラムとは何でしょうか。 ここでは、次のように用語を定めます。
アルゴリズムの説明で、問題解決と言われても、ピンと来ないかもしれません。 例として、次の問題を考えます。
与えられた文字列が回文か否かを判定せよ。 ここで回文とは、「たけやぶやけた」のように、左から読んでも右から読んでも同じになる文字列のことである。
この問題は、次のような方法で解決できます。
今、「いるかはまるい」という文字列が与えられたとします。 s1 は「いるかはまるい」に、 s2 は「いるまはかるい」になります。 左から一文字ずつ比較しますと、3文字目で違いが見つかりますので、"No"と答えます。 一方、「たけやぶやけた」の場合は、 s1 は「たけやぶやけた」に、 s2 も「たけやぶやけた」になります。 左から一文字ずつ比較しても違いは見つかりませんので、"Yes"と答えるというわけです。
この方法は、回文を判定するという問題を解決するものです。 したがって、回文判定のアルゴリズムなのです。
アルゴリズムは必ずしも一つとは限りません。 以下も回文判定のアルゴリズムです。
アルゴリズムが分かっていましても、そのままではコンピュータは問題解決をしてくれません。 コンピュータが日本語を理解するわけでもありませんし、どうやって「左右を逆転した文字列を生成」するのかも、はっきりしていません。 コンピュータに問題解決をしてもらうためには、コンピュータに処理できるような形で、アルゴリズムを具体的に表現する必要があります。 この表現のための言語がプログラミング言語であり、表現自身がプログラムです。
Javaはプログラミング言語のひとつです。 この授業の目的は、アルゴリズムをJavaのプログラムで表現し、コンピュータに問題解決をさせることであると言えます。 Java言語を覚えることと、アルゴリズムを見つけることは、無関係ではありません。 Javaの知識があればこそ、Javaで表現しやすいアルゴリズムが構成できるからです。 授業では、Java言語、アルゴリズム、およびプログラミングを並行して身につけることにします。
なお、プログラミング言語はJavaの他にもたくさんあります。 現在よく使われいるのは、C, C++, Javaです。 それなりに使われているのは、Fortran, Cobol, Lisp, Basic, Pascal, Prologといったところです。 プログラミング言語が変われば、解決しやすい問題の種類や、プログラムに対する考え方が変わります。 今はJavaで精一杯かもしれませんが、色々なプログラミング言語を経験し、問題や考え方に応じてプログラミング言語を選べるようなるのが理想的です。
プログラムの一部や全部の説明文がプログラムの中に書けますと、プログラマにとってプログラムが理解しやすくなります。
このような説明文を
コメント
(
comment
)
とよびます。
Javaコンパイラ(javac)は、プログラムに記号
//
が現れますと、そこから行末までを無視します。
そこにコメントを書けば、プログラムに影響を与えずにプログラムの説明ができます。
次のプログラムはコメントの使用例です。
class GoodMorning { // b00a001, Kyoko Azuma, Sep. 26, 2002 public static void main (String[] args) { System.out.println("Good morning!"); // Say good morning. } }
また、記号
/*
と
*/
に囲まれた部分も無視されます。
このふたつは同じ行にある必要はありませんので、たくさんの行を一度にコメント指定できます。
ただし、このコメントは入れ子にできません。
例えば、
System.out.println("Good morning!"); /* System.out.println("----------"); System.out.println("----------"); */ System.out.println("Good afternoon!");
という部分をコメント指定しようとして、
/* System.out.println("Good morning!"); /* System.out.println("----------"); System.out.println("----------"); */ System.out.println("Good afternoon!"); */
と書きましても、最初の
*/
までがコメントだと見なされてしまいます。
プログラムの行頭のスペース(字下げ)は インデント ( indent ) とよばれます。 Javaコンパイラ(javac)は行頭のスペースを無視します。 インデントをうまく使いますと、プログラムの構造を見やすくできます。
上記のプログラムでインデントを用いませんと
class GoodMorning { // b00a001, Kyoko Azuma, Sep. 26, 2002 public static void main (String[] args) { System.out.println("Good morning!"); // Say good morning. } }
となります。
最後の2つの閉じブレース(
}
)がそれぞれどの開きブレース(
{
)に対応しているかが分かりにくいです。
インデントを用いずに長いプログラムを書きますと、ブレースの対応が分からなくなり、プログラムの構造を見えなくしてしまいます。
前々回の授業では、Javaアプリケーションの例として、端末エミュレータにGoodMorning!と出力するプログラムを動かしてみました。 また、前回は、アプレットの例として、絵を描くプログラムを作成しました。 今回は、再びアプリケーションに戻りまして、数(特に整数)を取り扱うことにします。
次のプログラムを動かしますと、端末エミュレータで以下のような出力が得られます。
/* 1*/ class ExpressionTest { /* 2*/ public static void main (String[] args) { /* 3*/ System.out.println(250 + 100); /* 4*/ System.out.println(250 - 100); /* 5*/ System.out.println(250 * 100); /* 6*/ System.out.println(250 / 100); /* 7*/ System.out.println(250 % 100); /* 8*/ System.out.println(1000 + 250 * 3); /* 9*/ } /*10*/ }
b00a001@Ampere:~/java% javac ExpressionTest.java b00a001@Ampere:~/java% java ExpressionTest 350 150 25000 2 50 1750 b00a001@Ampere:~/java%
プログラム中の
250 + 100
,
250 - 100
などは
式
(
expression
)
とよばれるものです。
プログラムを動かしますと、式が計算されているのが分かります。
ここで、記号
*
が掛け算を表していることに注意してください。
また、記号
/
は割り算を表していますが、この場合は2余り50という計算をして、2を計算結果としています。
余りを求めるには、
/
の代わりに
%
を書きます。
+
,
-
,
*
,
/
,
%
などを
演算子
(
operator
)
とよびます。
int
型)の演算子
記号 | 演算 | 例 |
---|---|---|
+ |
足し算 | 19 + 3 ⇒ 22 |
- |
引き算 | 19 - 3 ⇒ 16 |
* |
掛け算 | 19 * 3 ⇒ 57 |
/ |
割り算 | 19 / 3 ⇒ 6 |
% |
割った余り | 19 % 3 ⇒ 1 |
上記の最後の出力を見ますと、式
1000 + 250 * 3
の計算は、はじめに掛け算をして、次に足し算をしていることが分かります。
これは、演算子
+
より
*
のほうが優先順位が高いと決められていて、式は優先順位の高い演算子から順に計算されるからです。
もし、足し算を先に計算したければ、括弧を使って
(1000 + 250) * 3
と書いてください。
この式の計算結果は3750となります。
演算子の優先順位を簡単に説明しますと、まず括弧の中が最優先で計算されます。
次に演算子
*
,
/
, および
%
が優先します。
最も優先順位が低いのは、演算子
+
と
-
です。
ここで注意すべきことは、
+
と
-
は同じ優先順位であり、これらが続いているときは左から右に計算されることです。
例えば、式
5 - 3 + 1
は
(5 - 3) + 1
と見なされ、3という計算結果になります。
演算子
*
,
/
,
%
についても同様です。
プログラムでは、 変数 ( variable ) というものが重要な役割を果たします。 変数とは、数などのデータが格納できる「入れ物」であると考えてください。 次の図は変数のイメージです。
変数には名前がついています。
これを
変数名
(
variable name
)
とよびます。
この場合は
x
です。
また、変数にはデータがひとつ格納できます。
これを変数の
値
(
value
)
とよびます。
この場合、変数
x
の値は100です。
変数を使えるようにするには、変数の 宣言 ( declaration ) という手続きが必要です。 変数にデータを格納するには、 代入文 ( assignment statement ) というものを用います。 変数に格納されたデータを取り出すには、式の中で数の代わりに変数名を書きます。
以下は変数を使ったプログラムの例です。
/* 1*/ class VariableTest { /* 2*/ public static void main (String[] args) { /* 3*/ int x; /* 4*/ x = 100; /* 5*/ System.out.println(x); /* 6*/ } /* 7*/ }
b00a001@Ampere:~/java% javac VariableTest.java b00a001@Ampere:~/java% java VariableTest 100 b00a001@Ampere:~/java%
3行目では、変数の宣言を行って、変数を使えるようにしています。
変数名を
x
とし、ここに格納するデータの種類(型といいます)は整数(
int
型)だと言っています。
4行目は代入文です。
変数
x
にデータ100を格納します。
代入文は、一般に
variable = expression;
という形をとります。 式 expression の計算結果を変数 variable に格納するということです。 単なる数も式の一種だということに注意してください。
5行目は結果の出力です。
変数
x
にはデータ100が格納されていますので、あたかも
System.out.println(100);
と書いたように振舞います。
なお、変数名はプログラマが決めます。 アルファベットの大文字か小文字で始まり、アルファベットの大文字、小文字、数字、アンダースコア(_)を並べた単語が使えます。 ただし、次の単語はJavaで特別な意味を持ちますので、変数名としては使えません。
A | abstract . |
---|---|
B | boolean ,break ,byte ,byvalue . |
C | case ,cast ,catch ,char ,class ,const ,continue . |
D | default ,do ,double . |
E | else ,extends . |
F | final ,finally ,float ,for ,future . |
G | generic ,goto . |
I | if ,implements ,import ,inner ,instanceof ,int ,interface . |
L | long . |
N | native ,new . |
O | operator ,outer . |
P | package ,private ,protected ,public . |
R | rest ,return . |
S | short ,static ,super ,switch ,synchronized . |
T | this ,throw ,throws ,transient ,try . |
V | var ,void ,volatile . |
W | while |
また、
null
,
true
,
false
も変数名としては使えません。
次のプログラムはいくつかの変数を使う例です。
/* 1*/ class SomeVariables { /* 2*/ public static void main (String[] args) { /* 3*/ int temp1, temp2, temp3; /* 4*/ temp1 = 300; /* 5*/ temp2 = 200; /* 6*/ temp3 = 4 * temp1 + 3 * temp2; /* 7*/ System.out.println(temp3); /* 8*/ System.out.println(4 * 300 + 3 * 200); /* 9*/ } /*10*/ }
b00a001@Ampere:~/java% javac SomeVariables.java b00a001@Ampere:~/java% java SomeVariables 1800 1800 b00a001@Ampere:~/java%
3行目で、3つの変数
temp1
,
temp2
,
temp3
を宣言します。
これは、変数の宣言
int temp1; int temp2; int temp3;
をまとめたものです。
6行目で、変数
temp3
に式
4 * temp1 + 3 * temp2
の値を代入します。
変数
temp1
の値は300で、
temp2
の値は200ですので、4×300+3×200を計算して、この値1800が変数
temp3
に格納されます。
前小節では次のようなプログラムを動かしました。
/* 1*/ class VariableTest { /* 2*/ public static void main (String[] args) { /* 3*/ int x; /* 4*/ x = 100; /* 5*/ System.out.println(x); /* 6*/ } /* 7*/ }
変数の宣言とデータの格納は一緒に行うことができます。
この操作を変数の
初期化
(
initialization
)
とよび、そのデータをその変数の
初期値
(
initial value
)
とよびます。
次のプログラムの3行目で、変数
x
を100に初期化しています。
/* 1*/ class VariableTest2 { /* 2*/ public static void main (String[] args) { /* 3*/ int x = 100; /* 4*/ System.out.println(x); /* 5*/ } /* 6*/ }
次のように書きますと、複数の変数が初期化できます。
int x = 100, y = 200;
次のように、変数の初期化と単なる宣言を混ぜることもできます。
int x = 100, y = 200, z;
今までの例では、変数に格納されたデータは特に変更されませんでした。 一般的には、変数に格納されたデータは何度も変更されます。
/* 1*/ class VariableTest3 { /* 2*/ public static void main (String[] args) { /* 3*/ int x = 100; /* 4*/ x = x + 1; /* 5*/ System.out.println(x); /* 6*/ } /* 7*/ }
b00a001@Ampere:~/java% javac VariableTest3.java b00a001@Ampere:~/java% java VariableTest3 101 b00a001@Ampere:~/java%
このプログラムは、いったん変数
x
にデータ100を格納した後、それを1増加させるものです。
4行目は、変数
x
の値に1をたしたものを変数
x
に格納する代入文です。
x
と
x + 1
が等しいと言っているわけではありません。
このイメージは次の図のようになります。
変数の値を1増加させることは頻繁に行われますので、省略形が用意されています。
x++;
で
x = x + 1;
と同じことが行われます。
変数の値を1減少させることにつきましても、
x = x - 1;
を
x--;
と省略することができます。
/* 1*/ class VariableTest4 { /* 2*/ public static void main (String[] args) { /* 3*/ int x = 100, y = 200; /* 4*/ x++; /* 5*/ y--; /* 6*/ System.out.println(x); /* 7*/ System.out.println(y); /* 8*/ } /* 9*/ }
b00a001@Ampere:~/java% javac VariableTest4.java b00a001@Ampere:~/java% java VariableTest4 101 199 b00a001@Ampere:~/java%
変数の使用例として、次の問題を考えます。
A子は店に行き、120円の缶ジュースを3本と150円のペットボトルを1本買いました。 A子はいくら支払わなければいけないでしょうか。 (この店は内税とします。)
この問題を解決するのに、3×120+150=510 と一気に計算はせず、レジの計算をまねることにします。
このアルゴリズムをプログラムにしますと、次のようになります。
/* 1*/ class SomeDrinks { /* 2*/ public static void main (String[] args) { /* 3*/ int amount = 0; /* 4*/ System.out.println(amount); /* 5*/ amount = amount + 3 * 120; /* 6*/ System.out.println(amount); /* 7*/ amount = amount + 150; /* 8*/ System.out.println(amount); /* 9*/ } /*10*/ }
b00a001@Ampere:~/java% javac SomeDrinks.java b00a001@Ampere:~/java% java SomeDrinks 0 360 510 b00a001@Ampere:~/java%
次の問題を考えます。
A子は銀行に行き、機械で28,000円を引き出しました。 機械は、一万円札、五千円札、千円札をそれぞれ何枚用意しなければいけないでしょうか。 (この機械は千円単位しか受け付けず、十分に紙幣を保持しているものとします。)
この問題を次のように解決します。
このアルゴリズムをプログラムにしてください。
b00a001@Ampere:~/java% javac BankMachine.java b00a001@Ampere:~/java% java BankMachine 2 1 3 b00a001@Ampere:~/java%
今日の演習3に従ってJavaプログラムを作成し、そのプログラムをkonishi@twcu.ac.jpあてにメールで提出してください。 メールには、学生番号、氏名、科目名、授業日(10/10)を明記してください。