006-002-002

かけ算の練習表を作ろう

中級

問題説明

解説

1. 問題の背景と目的

この問題では、for文のネスト(入れ子構造)を使ってかけ算の練習表を作成します。ネストしたループは、表やグリッド状のデータを扱う際に非常に重要な技術です。実務では、データの集計や多次元配列の処理など、さまざまな場面で使用されます。

この学習を通じて、繰り返し処理の中でさらに繰り返し処理を行う方法を理解し、より複雑なプログラムを書く基礎を身につけることができます。

2. 前提知識

この問題を解くために必要な基礎知識:

  • for文の基本: for (初期化; 条件; 更新) { 処理 } の構文
  • 変数の宣言と使用: int型の変数を宣言し、演算に使用する方法
  • Scanner クラス: キーボードからの入力を受け取る方法
  • 条件分岐: if文を使った入力値の検証
  • 算術演算子: かけ算(*)や比較演算子(<, >, <=, >=)の使い方

3. ネストしたfor文の仕組み

ネストしたfor文は、外側のループが1回実行されるたびに、内側のループが最初から最後まで完全に実行されます。

実行の流れ(n=2の場合)

外側ループ i=1:
  内側ループ j=1: 1 x 1 = 1
  内側ループ j=2: 1 x 2 = 2
  ...
  内側ループ j=9: 1 x 9 = 9
  
外側ループ i=2:
  内側ループ j=1: 2 x 1 = 2
  内側ループ j=2: 2 x 2 = 4
  ...
  内側ループ j=9: 2 x 9 = 18
```java

## 4. コード解説(ステップバイステップ)

### ステップ1: 入力の受け取りと検証

```java
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();

if (n < 1 || n > 9) {
    System.out.println("Error: Input must be between 1 and 9");
    sc.close();
    return;
}
```java

まず、Scannerオブジェクトを作成してキーボードから整数を読み取ります。次に、入力値が1から9の範囲内にあるかを検証します。範囲外の場合はエラーメッセージを表示して処理を終了します(早期リターンパターン)。

この検証は、プログラムが想定外の動作をしないようにするための「防御的プログラミング」の一例です。

### ステップ2: 外側のループ

```java
for (int i = 1; i <= n; i++) {
    // 各段の処理
}
```java

外側のループは、1からnまでの段数を制御します。変数iは現在の段数を表します。

- 初期化: `int i = 1` (1段目から開始)
- 条件: `i <= n` (n段目まで繰り返す)
- 更新: `i++` (1段ずつ増やす)

### ステップ3: 内側のループ

```java
for (int j = 1; j <= 9; j++) {
    int result = i * j;
    System.out.println(i + " x " + j + " = " + result);
}
```java

内側のループは、各段について1から9までの数をかけ算します。変数jは「何倍するか」を表します。

各繰り返しで、`i * j` の計算結果を変数resultに格納し、それを指定された形式で出力します。

### ステップ4: リソースのクローズ

```java
sc.close();
```java

使い終わったScannerオブジェクトを閉じます。これはメモリリークを防ぐための重要な処理です。

## 5. よくある間違い

### 間違い1: ループの条件設定ミス

```java
// ❌ 間違い
for (int i = 1; i < n; i++) {  // n段目が含まれない
```java

**理由**: `i < n` だと、iがnと等しい場合に条件が偽になり、n段目が表示されません。

```java
// ✅ 正しい
for (int i = 1; i <= n; i++) {  // n段目まで含む
```java

### 間違い2: <a href="https://javadrill.tech/problems/001">変数</a>のスコープ

```java
// ❌ 間違い
int result;
for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= 9; j++) {
        result = i * j;  // 毎回上書きされるが問題ない
    }
}
System.out.println(result);  // 最後の結果しか出力されない
```java

**理由**: 出力がループの外にあるため、最後の計算結果しか表示されません。

```java
// ✅ 正しい
for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= 9; j++) {
        int result = i * j;
        System.out.println(i + " x " + j + " = " + result);
    }
}
```java

### 間違い3: 入力検証の欠落

```java
// ❌ 間違い
int n = sc.nextInt();
for (int i = 1; i <= n; i++) {  // n=0や負の値で動作がおかしくなる
```java

**理由**: 入力検証がないと、想定外の値でループが実行されない、または無限ループになる可能性があります。

```java
// ✅ 正しい
if (n < 1 || n > 9) {
    System.out.println("Error: Input must be between 1 and 9");
    return;
}
```java

## 6. 発展的な内容

さらに学習を深めるためのヒント:

- **3重ループ**: 3次元のデータ(例:年、月、日)を扱う際に使用
- **break文とcontinue文**: ループ内での制御フロー(特定条件でループを抜ける、スキップする)
- **拡張for文**: <a href="https://javadrill.tech/problems/004">配列</a>や<a href="https://javadrill.tech/problems/020">コレクション</a>を簡潔に処理する方法
- **実務での応用**: 表計算ソフトのような行列データの処理、画像処理(ピクセル単位の操作)など

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

次に学ぶべきトピックやこの問題と関連する概念:

- **<a href="https://javadrill.tech/problems/004">配列</a>とネストループ**: 2次元配列の初期化と走査(カテゴリ007)
- **<a href="https://javadrill.tech/problems/006/003">while文</a>のネスト**: 異なる繰り返し構文の組み合わせ(カテゴリ006-003)
- **<a href="https://javadrill.tech/problems/008">メソッド</a>の活用**: ネストループを<a href="https://javadrill.tech/problems/008">メソッド</a>に分割してコードを整理(カテゴリ008)

テストケース例

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

正常系
入力:
2
期待される出力:
1 x 1 = 1
1 x 2 = 2
1 x 3 = 3
1 x 4 = 4
1 x 5 = 5
1 x 6 = 6
1 x 7 = 7
1 x 8 = 8
1 x 9 = 9
2 x 1 = 2
2 x 2 = 4
2 x 3 = 6
2 x 4 = 8
2 x 5 = 10
2 x 6 = 12
2 x 7 = 14
2 x 8 = 16
2 x 9 = 18
正常系
入力:
3
期待される出力:
1 x 1 = 1
1 x 2 = 2
1 x 3 = 3
1 x 4 = 4
1 x 5 = 5
1 x 6 = 6
1 x 7 = 7
1 x 8 = 8
1 x 9 = 9
2 x 1 = 2
2 x 2 = 4
2 x 3 = 6
2 x 4 = 8
2 x 5 = 10
2 x 6 = 12
2 x 7 = 14
2 x 8 = 16
2 x 9 = 18
3 x 1 = 3
3 x 2 = 6
3 x 3 = 9
3 x 4 = 12
3 x 5 = 15
3 x 6 = 18
3 x 7 = 21
3 x 8 = 24
3 x 9 = 27

あなたの解答

現在のモード:● 自分のコード
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

残り 10 回実行可能