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

コンピュータIIB(Javaプログラミング入門)第11回

目次 索引
11.1 文字列
11.1.1 文字列の操作
11.1.2 文字列バッファ
11.1.3 整数と文字列
11.2 文字と文字列
11.2.1 文字の操作
11.2.2 文字列の使用例
11.3 演習11
11.4 レポート課題
11.5 参考文献
文字列バッファ 

11.1 文字列

11.1.1 文字列の操作

これまで文字列は、

int result = 12345679 * 9;
System.out.println("result: " + result);

のように画面出力のときのみ使ってきました。 実は、文字列は組み込みのクラスである String クラスのインスタンスです。 文字列はよく使われますので、便利な機能がいくつか用意されています。

まず、コンストラクタを使わなくてもインスタンスが生成できます。 コンストラクタを用いて

String s = new String();
s = "Good";

String s = new String("Good");

などと書かなくても、

String s = "Good";

でよいのです。

また、演算子 + が使えます。 これは、文字列を連接します。

String s1 = "Good";
String s2 = "morning!";
String s3 = s1 + " " + s2;

としますと、 s3 には文字列 "Good morning!" が格納されます。

文字列と数を演算子 + で結びますと、数が文字列に変換されてから連接されます。

int result = 12345679 * 9;
String s1 = "result = ";
String s2 = s1 + result;

としますと、 s2 には文字列 "result = 111111111" が格納されます。

String クラスのメソッドで重要なものは以下の通りです。

char charAt (int i)
そのインスタンスの i 番目の文字を返す。
boolean equals (String s)
そのインスタンスと文字列 s の内容が同じならば true を返す。 そうでなければ false を返す。
int length ()
そのインスタンスの文字数を返す。
static String valueOf (boolean b)
真理値 b を文字列に変換して返す。
static String valueOf (char c)
文字 c を文字列に変換して返す。
static String valueOf (int i)
整数 i を文字列に変換して返す。

なお、メソッドを呼び出すときには、 charint などは書きません。 また、 static と書いてあればクラスメソッド、書いてなければインスタンスメソッドです。 インスタンスメソッド methodname を呼び出すには、

instance.methodname(argument...)

と書きます。 クラス classname のクラスメソッド methodname を呼び出すには、

classname.methodname(argument...)

と書きます。

11.1.2 文字列バッファ

文字列、すなわち String クラスのインスタンスは、一度生成されますとその内容は変更できません。 文字列 "Good morning!" の mor を eve に置き換えることができないのです。 内容を変更するには、文字列ではなく文字列バッファというものを用います。 文字列バッファstring buffer ) とは、組み込みのクラス StringBuffer のインスタンスのことです。 文字列バッファに対しては、文字の置き換え、追加、挿入などができます。 文字列を加工するには、いったん文字列バッファに変換し、処理のあと再び文字列に変換すればよいのです。

文字列を文字列バッファに変換するには、 StringBuffer クラスのコンストラクタを用います。 逆に、文字列バッファを文字列に変換するには、インスタンスメソッド toString を呼び出します。

String s1 = "Good morning!";
StringBuffer s2 = new StringBuffer(s1);
s2.setCharAt(5, 'e');
s2.setCharAt(6, 'v');
s2.setCharAt(7, 'e');
String s3 = s2.toString();

としますと、 s3 には文字列 "Good evening!" が格納されます。 ここで、インスタンスメソッド setCharAt ( i , c )は、そのインスタンスの i 番目の文字を c に置き換えるものです。

StringBuffer クラスの重要なメソッドは以下の通りです。

StringBuffer append (String s)
そのインスタンスに文字列 s を追加する。
StringBuffer append (char c)
そのインスタンスに文字 c を追加する。
char charAt (int i)
そのインスタンスの i 番目の文字を返す。
StringBuffer insert (int i, String s)
そのインスタンスの i 番目の位置に文字列 s を挿入する。
StringBuffer insert (int i, char c)
そのインスタンスの i 番目の位置に文字 c を挿入する。
int length ()
そのインスタンスの文字数を返す。
void setCharAt (int i, char c)
そのインスタンスの i 番目の文字を文字 c に置き換える。
String toString ()
そのインスタンスを文字列に変換して返す。

11.1.3 整数と文字列

組み込みの Integer クラスでは、整数( int 型)の変換に関するメソッドがいくつか提供されています。 その中では、以下のものが重要です。

static int parseInt (String s)
文字列 s を整数( int 型)に変換して返す。
static String toString (int i)
整数( int 型)を文字列に変換して返す。

ここで、入力された整数をそのまま出力するプログラム

/*  1*/ import java.io.*;
/*  2*/
/*  3*/ class InputTest {
/*  4*/     public static void main (String[] args) throws IOException {
/*  5*/         InputStreamReader isr = new InputStreamReader(System.in);
/*  6*/         BufferedReader br = new BufferedReader(isr);
/*  7*/         int x;
/*  8*/         System.out.print("Enter a number: ");
/*  9*/         x = Integer.parseInt(br.readLine());
/* 10*/         System.out.println(x);
/* 11*/     }
/* 12*/ }
b04a001@AsiaA1:~/comp2b% javac InputTest.java
b04a001@AsiaA1:~/comp2b% java InputTest
Enter a number: 100
100
b04a001@AsiaA1:~/comp2b%

を思い出してください。 このプログラムの9行目の意味が、ここでやっと明らかになります。

このプログラムを実行しますと、式 br . readLine ()の値は入力された文字列になります。 上記の場合では、文字列 "100" です。 そして、クラスメソッド parseInt によって文字列 "100" が整数 100 に変換されます。 最後に、この整数 100 が変数 x に格納されるのです。


11.2 文字と文字列

11.2.1 文字の操作

前回説明した通り、文字は内部では整数として処理されます。 したがって、文字が等しいかどうかは、関係演算子 == を用いて表します。 また、 >< などは、文字符号の大小関係を意味します。

例えば、

if (c == 'Z') {
    ...
}

c が文字 Z ならば…ですし、

if (c > 'Z') {
    ...
}

c の文字符号が Z の文字符号より大きいならば…です。

文字を1増加させることは、文字符号を1増加させることになります。 ただし、このことを

c = c + 1;

と書きますと、エラーになります。 これは、足し算によって右辺が整数( int 型)と見なされるからです。 整数を文字に変換するには、

c = (char) (c + 1);

と書きます。 逆に、整数と見なされることを利用することもできます。 文字 c が数字である場合、式

c - '0'

はその数字の表す数になります。

文字に関するメソッドは、組み込みのクラスである Character クラスで提供されています。 この中で重要なものは以下の通りです。

static boolean isDigit (char c)
文字 c が数字ならば true を返す。 そうでなければ false を返す。
static boolean isLowerCase (char c)
文字 c がアルファベットの小文字ならば true を返す。 そうでなければ false を返す。
static boolean isSpace (char c)
文字 c がホワイトスペース(スペース、水平タブ、改行など)ならば true を返す。 そうでなければ false を返す。
static boolean isUpperCase (char c)
文字 c がアルファベットの大文字ならば true を返す。 そうでなければ false を返す。
static char toLowerCase (char c)
文字 c がアルファベットの大文字ならば、それを小文字に変換して返す。 そうでなければそのまま返す。
static char toUpperCase (char c)
文字 c がアルファベットの小文字ならば、それを大文字に変換して返す。 そうでなければそのまま返す。

11.2.2 文字列の使用例

ここで、文字と文字列を扱うプログラムの例を、いくつか紹介します。

最初のプログラムは、入力された文字列の中の小文字を、すべて大文字に置き換えるものです。 アルゴリズムの要点は、文字列の中の文字を一つずつ取り出し、それが小文字ならば大文字に置き換えることです。 ただし、文字列の変更はできませんので、いったん文字列バッファに変換してから置き換えを行い、再び文字列に変換します。

プログラムでは、12行目で文字列を変数 str に格納し、13行目でそれを文字列バッファに変換して変数 sb に格納します。 20行目で文字列バッファ sb を文字列に変換します。 長さを求める length , 文字を取り出す charAt , 文字を置き換える setCharAt , 文字列へ変換する toString は、すべて文字列バッファのインスタンスメソッドですので、 sb . methodname (...)という形式で呼び出します。 小文字かどうかを判定する isLowerCase と大文字にする toUpperCase は、 Character クラスのクラスメソッドですので、 Character . methodname (...)という形式で呼び出します。

/*  1*/ import java.io.*;
/*  2*/ 
/*  3*/ class StringCapitalize {
/*  4*/     public static void main (String[] args) throws IOException {
/*  5*/         InputStreamReader isr = new InputStreamReader(System.in);
/*  6*/         BufferedReader br = new BufferedReader(isr);
/*  7*/         int i;
/*  8*/         char ch;
/*  9*/         String str, result;
/* 10*/         StringBuffer sb;
/* 11*/         System.out.print("Enter a string: ");
/* 12*/         str = br.readLine();
/* 13*/         sb = new StringBuffer(str);
/* 14*/         for (i = 0; i < sb.length(); i++) {
/* 15*/             if (Character.isLowerCase(sb.charAt(i))) {
/* 16*/                 ch = Character.toUpperCase(sb.charAt(i));
/* 17*/                 sb.setCharAt(i, ch);
/* 18*/             }
/* 19*/         }
/* 20*/         result = sb.toString();
/* 21*/         System.out.println(result);
/* 22*/     }
/* 23*/ }
b04a001@AsiaA1:~/comp2b% java StringCapitalize
Enter a string: Good afternoon!
GOOD AFTERNOON!
b04a001@AsiaA1:~/comp2b%

次のプログラムは、入力された文字列を逆順にするものです。 アルゴリズムの要点は、始めに空の文字列バッファを用意し、文字列の右から一文字ずつ取り出して、それを文字列バッファに追加することです。

プログラムでは、9行目で空の文字列バッファを変数 sb 格納します。 長さを求める length と文字を取り出す chatAt は、文字列のインスタンスメソッドです。 文字を追加する append は、文字列バッファのインスタンスメソッドです。

/*  1*/ import java.io.*;
/*  2*/ 
/*  3*/ class StringReverse {
/*  4*/     public static void main (String[] args) throws IOException {
/*  5*/         InputStreamReader isr = new InputStreamReader(System.in);
/*  6*/         BufferedReader br = new BufferedReader(isr);
/*  7*/         int i;
/*  8*/         String str, result;
/*  9*/         StringBuffer sb = new StringBuffer("");
/* 10*/         System.out.print("Enter a string: ");
/* 11*/         str = br.readLine();
/* 12*/         for (i = str.length() - 1; i >= 0; i--) {
/* 13*/             sb.append(str.charAt(i));
/* 14*/         }
/* 15*/         result = sb.toString();
/* 16*/         System.out.println(result);
/* 17*/     }
/* 18*/ }
b04a001@AsiaA1:~/comp2b% java StringReverse
Enter a string: ABCDE
EDCBA
b04a001@AsiaA1:~/comp2b%

最後のプログラムは、入力された文字列の中に、A, B, Cがそれぞれ何回現れるかを数えるものです。 アルゴリズムの要点は、始めに変数 countA を用意し、文字列の中の文字を一つずつ取り出し、それがAならば countA の値を1増加させる、などとすることです。

プログラムでは、取り出した文字がAかどうかを判定するために、関係演算子 == を使っています。

/*  1*/ import java.io.*;
/*  2*/ 
/*  3*/ class CountABC {
/*  4*/     public static void main (String[] args) throws IOException {
/*  5*/         InputStreamReader isr = new InputStreamReader(System.in);
/*  6*/         BufferedReader br = new BufferedReader(isr);
/*  7*/         int i, countA = 0, countB = 0, countC = 0;
/*  8*/         String str;
/*  9*/         System.out.print("Enter a string: ");
/* 10*/         str = br.readLine();
/* 11*/         for (i = 0; i < str.length(); i++) {
/* 12*/             if (str.charAt(i) == 'A') {
/* 13*/                 countA++;
/* 14*/             } else if (str.charAt(i) == 'B') {
/* 15*/                 countB++;
/* 16*/             } else if (str.charAt(i) == 'C') {
/* 17*/                 countC++;
/* 18*/             } else {
/* 19*/             }
/* 20*/         }
/* 21*/         System.out.println("A: " + countA);
/* 22*/         System.out.println("B: " + countB);
/* 23*/         System.out.println("C: " + countC);
/* 24*/     }
/* 25*/ }
b04a001@AsiaA1:~/comp2b% java CountABC
Enter a string: ABCABA
A: 3
B: 2
C: 1
b04a001@AsiaA1:~/comp2b%

11.3 演習11

入力された文字列をローマ数字と見なして、その値(算用数字)を出力してください。 ローマ数字と算用数字の対応は以下の通りです。

表 11.1  ローマ数字と算用数字の対応
ローマ数字 算用数字
I 1
V 5
X 10

話を簡単にするために、ローマ数字でない文字は読み飛ばすことにします。

アルゴリズムの要点は、文字列の中の文字を一つずつ取り出して、もしIならば変数の値を1増加させる、などとすることです。

このアルゴリズムを具体的にして、プログラムを作成してください。

b04a001@AsiaA1:~/comp2b% java RomanNumeral
Enter a string: III
3
b04a001@AsiaA1:~/comp2b% java RomanNumeral
Enter a string: XII
12
b04a001@AsiaA1:~/comp2b% java RomanNumeral
Enter a string: XXV
25
b04a001@AsiaA1:~/comp2b%

余力のある人は、以下の表にも従ってください。

表 11.2  ローマ数字と算用数字の対応
ローマ数字 算用数字
IV 4
IX 9

ローマ数字では、同じ文字を4つ以上は並べません。 例えば、4は5-1と考えて、V(=5)の左にI(=1)を書きます。

b04a001@AsiaA1:~/comp2b% java RomanNumeral
Enter a string: XIV
14
b04a001@AsiaA1:~/comp2b% java RomanNumeral
Enter a string: XIX
19
b04a001@AsiaA1:~/comp2b%

11.4 レポート課題

今日の演習11の答案(Javaプログラム)をメールで提出してください。 メールの送信には学内のコンピュータ(メール・サーバ)を用い、送信先はkonishi@twcu.ac.jpとします。 メールの本文には、学生番号、氏名、科目名、授業日(7月1日)を明記してください。


11.5 参考文献


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

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