Skip to content
Playground

演習: メソッド

各問題のコードは、Main クラスの中に書く前提です。main メソッドの外に問題で指定されたメソッドを static として定義し、main から呼び出してください。

public class Main {
public static void main(String[] args) {
// ここからメソッドを呼び出す
}
// 問題で指定されたメソッドをここに定義する
static 戻り値の型 メソッド名(引数の型 引数名, ...) {
// 処理
return 値;
}
}

名前を引数として受け取り、Hello, の後ろに名前と ! をつないだ文字列を返すメソッド greet を作成してください。

System.out.println(greet("Java"));
System.out.println(greet("World"));

出力例:

Hello, Java!
Hello, World!
ヒント

メソッドの基本構文:

static 戻り値の型 メソッド名(引数の型 引数名) {
return 値;
}

文字列を返すので戻り値の型は String、引数も String です。文字列の連結には + 演算子が使えます。

底辺 base と高さ height を受け取り、三角形の面積を返すメソッド triangleArea を作成してください。

System.out.println("面積: " + triangleArea(5.0, 3.0));
System.out.println("面積: " + triangleArea(8.0, 4.5));

出力例:

面積: 7.5
面積: 18.0
ヒント

引数を2つ取るメソッドは、カンマで区切って書きます。

static 戻り値の型 メソッド名(引数1の型 引数1, 引数2の型 引数2) {
...
}

三角形の面積は 底辺 × 高さ ÷ 2double 型で計算します。

整数が偶数なら true、奇数なら false を返すメソッド isEven を作成してください。

System.out.println(isEven(4));
System.out.println(isEven(7));
System.out.println(isEven(0));
System.out.println(isEven(-2));

出力例:

true
false
true
true
ヒント

戻り値の型は boolean% 演算子で 2 で割った余りを取り、それが 0 かどうかを判定します。return n % 2 == 0; のように、比較結果を直接 return できます。

整数配列を受け取り、その合計を返すメソッド sum を作成してください。

int[] numbers = {3, 1, 4, 1, 5, 9, 2, 6};
System.out.println(sum(numbers));
int[] empty = {};
System.out.println(sum(empty));

出力例:

31
0
ヒント

配列を引数として受け取るには、引数の型を int[] にします:

static int sum(int[] arr) {
...
}

メソッドの中で for ループで配列を走査し、合計を計算して返します。空配列(要素数 0)でも正しく 0 を返すよう、初期値を 0 にしておけば自然に対応できます。

6-E. 配列の最大値(メソッド化)

Section titled “6-E. 配列の最大値(メソッド化)”

整数配列を受け取り、最大値を返すメソッド max を作成してください。配列が空の場合は Integer.MIN_VALUE を返します。

int[] numbers = {15, 22, 18, 30, 25, 17, 28};
System.out.println(max(numbers));

出力例:

30
ヒント

最初の要素を仮の最大値とし、残りの要素と順に比較していきます。空配列のチェックを最初に入れて、空ならすぐ Integer.MIN_VALUE を返します。

Integer.MIN_VALUEint の最小値(-2147483648)を表す定数です。これを返しておけば、呼び出し側は max の戻り値が他のどの整数より大きくないと扱えるため、後続の比較処理で安全に使えます。

6-F. 配列の全要素を2倍にする(参照渡し)

Section titled “6-F. 配列の全要素を2倍にする(参照渡し)”

整数配列を受け取り、すべての要素を2倍に書き換える void メソッド doubleAll を作成してください。main から呼び出した後、元の配列が変更されていることを確認します。

int[] numbers = {1, 2, 3, 4, 5};
System.out.print("変更前: ");
for (int n : numbers) System.out.print(n + " ");
System.out.println();
doubleAll(numbers);
System.out.print("変更後: ");
for (int n : numbers) System.out.print(n + " ");
System.out.println();

出力例:

変更前: 1 2 3 4 5
変更後: 2 4 6 8 10

各行末の半角スペースは、問題文の出力コードをそのまま使った場合の自然な結果なので気にしなくて構いません。

ヒント

戻り値が無いメソッドは void で宣言し、return 文を省略できます(あるいは return; だけ書く)。

static void メソッド名(引数) {
// 処理
}

Java では、配列を引数として渡すと参照が渡されるため、メソッドの中で配列の要素を変更すると、呼び出し元の配列にも反映されます。一方、int などのプリミティブ型の引数は値がコピーされて渡されるので、メソッド内で書き換えても呼び出し元には影響しません。

6-G. BMI 判定(メソッドの合成)

Section titled “6-G. BMI 判定(メソッドの合成)”

体重(kg)と身長(m)から BMI を計算するメソッド bmi と、BMI 値を受け取って判定文字列を返すメソッド bmiCategory を作成し、main から両方を呼び出して結果を表示してください。

判定の区分:

BMI判定
18.5 未満痩せ型
18.5 以上 25 未満普通体重
25 以上 30 未満肥満(1度)
30 以上肥満(2度以上)
double weight = 65.0;
double height = 1.70;
double b = bmi(weight, height);
System.out.printf("BMI: %.2f%n", b);
System.out.println("判定: " + bmiCategory(b));

出力例:

BMI: 22.49
判定: 普通体重
ヒント

BMI の計算式: 体重 / (身長 × 身長)

bmiCategory メソッドの中では if-else if で判定します。switch 式の case は同値比較しかできず、< 25 のような範囲条件は書けないため、ここでは switch 式は使えません。

main から bmi の結果を変数に保存して bmiCategory に渡す方法のほか、bmiCategory(bmi(weight, height)) のように直接ネストして呼び出すこともできます。

6-H. GCD と LCM(メソッドの合成)

Section titled “6-H. GCD と LCM(メソッドの合成)”

2つの正の整数の最大公約数(GCD)を返すメソッド gcd と、最小公倍数(LCM)を返すメソッド lcm を作成してください。lcm の中で gcd を呼び出します。

System.out.println("GCD(48, 36) = " + gcd(48, 36));
System.out.println("LCM(48, 36) = " + lcm(48, 36));
System.out.println("GCD(17, 5) = " + gcd(17, 5));
System.out.println("LCM(17, 5) = " + lcm(17, 5));

出力例:

GCD(48, 36) = 12
LCM(48, 36) = 144
GCD(17, 5) = 1
LCM(17, 5) = 85
ヒント

GCD はユークリッドの互除法で計算できます。

LCM は GCD を使って次のように計算できます:

LCM(a, b) = a × b / GCD(a, b)

lcm メソッドの中で gcd(a, b) を呼び出し、結果を割り算に使います。1つのメソッドの中で別のメソッドを呼び出してロジックを組み立てる、ヘルパーメソッドの合成パターンです。

正の整数 n 以下の完全数をすべて列挙し、半角スペース区切りで1行に出力してください。完全数とは、自分自身を除く約数の合計が自分自身と等しい正の整数です(例: 6 = 1 + 2 + 3)。

ヘルパーメソッド properDivisorSum(int n) を作り、n の自分自身を除く約数の合計を返すようにします。それを使って、1 から n までを走査し、完全数を見つけます。

int n = 10000;

出力例:

6 28 496 8128
ヒント

properDivisorSum(int n) の実装:

  • 1 から n - 1 まで走査し、n を割り切る数(n % i == 0)を合計する
  • 1 から √n まで走査するほうが効率的ですが、今回は素直に n - 1 までで十分です

main では for ループで 1 から n まで走査し、properDivisorSum(i) == i なら出力します。

6 の自分自身を除く約数は 1, 2, 3 で合計 6 なので完全数。281+2+4+7+14=28 で完全数です。

整数 xn 乗した値(x^n)を再帰で計算するメソッド power を作成してください。n は 0 以上の整数とします。

System.out.println(power(2, 10));
System.out.println(power(3, 5));
System.out.println(power(5, 0));
System.out.println(power(7, 1));

出力例:

1024
243
1
7
ヒント

再帰メソッドの基本構造:

  • 基底ケース(base case): 再帰せずに直接答えが分かるケース
  • 再帰ケース(recursive case): より小さな問題に分解して、自分自身を呼び出すケース

累乗の定義:

  • x^0 = 1(基底ケース)
  • x^n = x × x^(n-1)(再帰ケース)

これをそのままメソッドに翻訳します。基底ケースを忘れると再帰呼び出しが止まらなくなり、StackOverflowError が発生します。

ハノイの塔の手順を出力するメソッド hanoi を作成してください。

ハノイの塔のルール:

  • 3 本の柱(ABC)がある
  • A には n 枚の円盤が大きい順に積まれている
  • すべての円盤を C に移す
  • 一度に動かせるのは1枚だけ
  • 大きい円盤の上に小さい円盤を置くのはOKだが、その逆はNG

B を作業用として使い、A のすべての円盤を C に移す手順を再帰で求め、各移動を1行ずつ出力します。

hanoi(3, "A", "C", "B");

第1引数 n、第2引数 from、第3引数 to、第4引数 via(作業用の柱)。

出力例(n=3 のとき):

A -> C
A -> B
C -> B
A -> C
B -> A
B -> C
A -> C

7手で完了します(一般に n 枚の場合は 2^n - 1 手)。

ヒント

ハノイの塔の解法は再帰的に表現できます。n 枚を from から to に移すには:

  1. 上の n - 1 枚を、to を作業用として from から via に移す(再帰)
  2. 一番下の 1 枚を from から to に移す(出力)
  3. via にある n - 1 枚を、from を作業用として via から to に移す(再帰)

基底ケースは n が 0 のときに何もしない(または n が 1 のときに直接 from -> to を出力する)形になります。

hanoi メソッドが自分自身を 2 回呼び出すのが特徴で、再帰ツリーが分岐します。これが手数が指数的に増える(2^n - 1)理由です。

文字列を k 文字分シフトして暗号化するメソッド encrypt と、暗号文を元に戻す decrypt を作成してください。

ルール:

  • 大文字・小文字のアルファベットのみ変換する(英字以外の文字はそのまま)
  • 大文字は大文字、小文字は小文字に保つ
  • 例: k = 3 のとき、'A''D''X''A'Z を超えたら最初に戻る、26文字を1周)
String original = "Hello, World!";
int k = 3;
String encrypted = encrypt(original, k);
String decrypted = decrypt(encrypted, k);
System.out.println("元: " + original);
System.out.println("暗号: " + encrypted);
System.out.println("復号: " + decrypted);

出力例:

元: Hello, World!
暗号: Khoor, Zruog!
復号: Hello, World!
ヒント

char と整数の演算が使えます:

  • 'A''a'char 型ですが、int として演算できます('A' = 65'a' = 97
  • 文字 c がアルファベットの何番目かは、大文字なら c - 'A'、小文字なら c - 'a' で計算できます
  • 26 を超えないようにするには % 26 を使います

シフト後の文字を作る式:

  • 大文字: (char) ('A' + (c - 'A' + k) % 26)
  • 小文字: (char) ('a' + (c - 'a' + k) % 26)

decrypt(s, k)encrypt(s, 26 - k % 26) と書くと、逆方向のシフトを正のシフトとして表現できるので、% 演算の符号の挙動を気にせずに済みます。

文字列を1文字ずつ走査するには s.charAt(i) を使い、結果を String に組み立てます(+ 演算子による文字列連結、または StringBuilder)。