005-002-003

会員ランク判定プログラム

中級

問題説明

【解説】

1. 問題の背景と目的

この問題では、if-else文を使った条件分岐の基本を学びます。ポイント数という具体的な数値を基準に、3つの会員ランク(ゴールド、シルバー、ブロンズ)を判定します。このような条件分岐は、実際のシステム開発でも頻繁に使用される重要な技術です。例えば、ECサイトの会員ランク判定、税金計算、成績評価など、様々な場面で活用されます。

2. 前提知識の詳細説明

変数とは

変数は、プログラムが実行中にデータを一時的に記憶しておくための「名前付きの箱」です。この問題ではint pointsという変数を使い、ユーザーが入力したポイント数を保存します。int型は整数(小数点のない数)を扱うデータ型です。

if-else文とは

if-else文は「もし〜ならば〜、そうでなければ〜」という条件分岐を実現する構文です。条件式がtrueの場合は対応するブロックが実行され、falseの場合は次の条件や最後のelse節が実行されます。

Scannerクラス

Scannerクラスは、キーボードからの入力を受け取るためのJavaの標準クラスです。new Scanner(System.in)でキーボード入力を読み取る準備をし、nextInt()メソッドで整数を受け取ります。

3. コードの行ごとの詳細解説

ステップ1: 入力の準備

Scanner sc = new Scanner(System.in);
int points = sc.nextInt();
```java
1行目でScannerオブジェクトを作成し、キーボード入力を受け取る準備をします。2行目で`nextInt()`を呼び出し、ユーザーが入力した整数を読み取って変数pointsに代入します。例えば「1500」と入力されると、pointsには整数値1500が格納されます。

### ステップ2: エラーチェック(負の値)
```java
if (points < 0) {
    System.out.println("Error: Points must be positive or zero");
}
```java
最初に負の値をチェックします。ポイント数は0以上でなければならないため、負の値が入力された場合はエラーメッセージを表示します。このように、想定外の値を先にチェックすることを「防御的プログラミング」と呼びます。

### ステップ3: ゴールド会員の判定
```java
else if (points >= 1000) {
    System.out.println("====================");
    System.out.println("Membership Card");
    System.out.println("====================");
    System.out.println("Level: Gold");
    System.out.println("Points: " + points);
    System.out.println("====================");
}
```java
エラーでない場合、次に1000ポイント以上かどうかをチェックします。`>=`<a href="https://javadrill.tech/problems/003">演算子</a>は「以上」を意味し、1000ちょうども含みます。条件がtrueなら会員カードの枠線を「=」で作り、ゴールド会員であることを表示します。

### ステップ4: シルバー会員の判定
```java
else if (points >= 500) {
    System.out.println("====================");
    System.out.println("Membership Card");
    System.out.println("====================");
    System.out.println("Level: Silver");
    System.out.println("Points: " + points);
    System.out.println("====================");
}
```java
ここに到達する時点で、pointsは既に1000未満であることが確定しています(前の条件がfalseだったため)。そのため、`points >= 500`だけをチェックすれば、500以上1000未満の範囲を判定できます。

### ステップ5: ブロンズ会員の判定
```java
else {
    System.out.println("====================");
    System.out.println("Membership Card");
    System.out.println("====================");
    System.out.println("Level: Bronze");
    System.out.println("Points: " + points);
    System.out.println("====================");
}
```java
最後のelse節は、前のすべての条件がfalseだった場合に実行されます。ここに到達する時点で、pointsは0以上500未満であることが確定しているため、追加の条件は不要です。

### ステップ6: リソースの解放
```java
sc.close();
```java
最後に`close()`メソッドを呼び出して、Scannerオブジェクトが使用していたリソース(メモリやシステムリソース)を解放します。これはプログラミングの良い習慣です。

## 4. よくある間違いと修正例

### 間違い1: 条件の順序が逆
```java
// ❌ 間違い
if (points >= 500) {
    System.out.println("Level: Silver");
} else if (points >= 1000) {
    System.out.println("Level: Gold");
}
```java
**理由**: 1500ポイントの場合、最初の条件`points >= 500`がtrueになってしまい、シルバー会員と判定されます。条件は上から順に評価されるため、大きい値から先にチェックする必要があります。

**正しい書き方**:
```java
// ✅ 正しい
if (points >= 1000) {
    System.out.println("Level: Gold");
} else if (points >= 500) {
    System.out.println("Level: Silver");
}
```java

### 間違い2: 境界値の扱いが不適切
```java
// ❌ 間違い
if (points > 1000) {  // 1000ちょうどが除外される
    System.out.println("Level: Gold");
}
```java
**理由**: `>`を使うと、1000ちょうどはゴールド会員に含まれなくなります。仕様では「1000ポイント以上」なので、`>=`を使う必要があります。

**正しい書き方**:
```java
// ✅ 正しい
if (points >= 1000) {  // 1000ちょうども含む
    System.out.println("Level: Gold");
}
```java

### 間違い3: 文字列連結の間違い
```java
// ❌ 間違い
System.out.println("Points: " points);  // +記号がない
```java
**理由**: Javaでは文字列と変数を連結する際には`+`演算子が必要です。これがないとコンパイルエラーになります。

**正しい書き方**:
```java
// ✅ 正しい
System.out.println("Points: " + points);
```java

## 5. 実践的なデバッグのヒント

### デバッグ方法1: 中間値の確認
もし期待通りの動作をしない場合、まず変数の値を確認しましょう:
```java
int points = sc.nextInt();
System.out.println("Debug: points = " + points);  // デバッグ用の出力
```java

### デバッグ方法2: 条件式の確認
条件式の結果を確認する:
```java
System.out.println("points >= 1000? " + (points >= 1000));
System.out.println("points >= 500? " + (points >= 500));
```java

### よく見るエラーメッセージ
- `InputMismatchException`: 数値以外の文字が入力された場合
- `NoSuchElementException`: 入力がない状態でnextInt()を呼んだ場合

## 6. 発展的な内容

### より効率的な実装
会員カードの枠線部分は重複しているので、メソッドに分けるとコードが読みやすくなります:
```java
private static void printMembershipCard(String level, int points) {
    System.out.println("====================");
    System.out.println("Membership Card");
    System.out.println("====================");
    System.out.println("Level: " + level);
    System.out.println("Points: " + points);
    System.out.println("====================");
}
```java

### 実務での応用例
実際の開発では、会員ランクごとに割引率を変えたり、特典を付与したりします:
```java
if (points >= 1000) {
    discount = 0.2;  // 20%割引
} else if (points >= 500) {
    discount = 0.1;  // 10%割引
} else {
    discount = 0.05; // 5%割引
}
```java

### パフォーマンスへの配慮
この問題の範囲では気にする必要はありませんが、条件が多数ある場合は、発生頻度の高い条件を先にチェックすると処理が速くなります。

## 7. 関連する学習項目

次に学ぶべきトピック:
- **switch**(カテゴリ005-003: より多くの分岐を扱う場合に便利
- **<a href="https://javadrill.tech/problems/003/003">論理演算子</a>**(カテゴリ005-004: 複数の条件を組み合わせる
- **ループ処理**(カテゴリ006: 繰り返し処理を学ぶ
- **メソッド**(カテゴリ008: 繰り返し使うコードをまとめる

この問題で学んだ条件分岐は、プログラミングの基本中の基本です。しっかり理解して、次のステップに進みましょう。

テストケース例

※ 出力例はプログラミングの国際標準に準拠し英語で表示しています

入力:
1500
期待される出力:
====================
Membership Card
====================
Level: Gold
Points: 1500
====================
入力:
750
期待される出力:
====================
Membership Card
====================
Level: Silver
Points: 750
====================
入力:
300
期待される出力:
====================
Membership Card
====================
Level: Bronze
Points: 300
====================
入力:
1000
期待される出力:
====================
Membership Card
====================
Level: Gold
Points: 1000
====================
入力:
500
期待される出力:
====================
Membership Card
====================
Level: Silver
Points: 500
====================
入力:
0
期待される出力:
====================
Membership Card
====================
Level: Bronze
Points: 0
====================
入力:
-100
期待される出力:
Error: Points must be positive or zero
入力:
-1
期待される出力:
Error: Points must be positive or zero
❌ テストに失敗したケースがあります
❌ エラー発生

あなたの解答

現在のモード: 自分のコード
import java.util.Scanner;

public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// ここにコードを書いてください

sc.close();
}
}
0 B / 5 MB

残り 8 回実行可能