はじめに
Java研修コーディング問題集の第4回は 配列 です。
配列は複数のデータをまとめて管理するための基本的なデータ構造です。宣言・初期化・要素へのアクセス・ループとの組み合わせをマスターしましょう。
難易度の見方
| マーク | 難易度 | 目安 |
|---|---|---|
| ⭐ | 基本 | 研修1週目レベル |
| ⭐⭐ | 応用 | 少し考える必要あり |
| ⭐⭐⭐ | チャレンジ | 複数の知識を組み合わせる |
問題1:配列の宣言と出力 ⭐
問題
以下の5人の名前を配列に格納し、拡張for文(for-each)を使ってすべて出力してください。
-
"佐藤","田中","鈴木","高橋","伊藤"
期待する出力
メンバー一覧:
1. 佐藤
2. 田中
3. 鈴木
4. 高橋
5. 伊藤
ヒント
- 通し番号をつけるには、別途カウンター変数が必要です
模範解答
public class Exercise01 {
public static void main(String[] args) {
String[] names = {"佐藤", "田中", "鈴木", "高橋", "伊藤"};
System.out.println("メンバー一覧:");
int index = 1;
for (String name : names) {
System.out.println(index + ". " + name);
index++;
}
}
}
ポイント: 拡張for文(for (型 変数 : 配列))は配列の全要素を順番に処理する場合に便利です。ただしインデックスが必要な場合は通常のfor文を使うか、別途カウンター変数を用意します。
問題2:合計と平均 ⭐
問題
テストの点数が格納された配列 {78, 92, 65, 88, 73} の合計と平均を計算して出力してください。平均は小数第1位まで表示してください。
期待する出力
点数: 78 92 65 88 73
合計: 396
平均: 79.2
模範解答
public class Exercise02 {
public static void main(String[] args) {
int[] scores = {78, 92, 65, 88, 73};
System.out.print("点数: ");
int sum = 0;
for (int i = 0; i < scores.length; i++) {
if (i > 0) {
System.out.print(" ");
}
System.out.print(scores[i]);
sum += scores[i];
}
System.out.println();
double average = (double) sum / scores.length;
System.out.println("合計: " + sum);
System.out.println("平均: " + String.format("%.1f", average));
}
}
ポイント: scores.length で配列の要素数を取得できます。平均を求めるとき、int同士の除算では小数が切り捨てられるため、(double) でキャストしています。
問題3:最大値と最小値 ⭐
問題
配列 {34, 67, 23, 89, 12, 56, 78} から最大値と最小値を見つけて出力してください。
期待する出力
配列: 34 67 23 89 12 56 78
最大値: 89
最小値: 12
模範解答
public class Exercise03 {
public static void main(String[] args) {
int[] numbers = {34, 67, 23, 89, 12, 56, 78};
System.out.print("配列: ");
for (int i = 0; i < numbers.length; i++) {
if (i > 0) System.out.print(" ");
System.out.print(numbers[i]);
}
System.out.println();
int max = numbers[0];
int min = numbers[0];
for (int i = 1; i < numbers.length; i++) {
if (numbers[i] > max) {
max = numbers[i];
}
if (numbers[i] < min) {
min = numbers[i];
}
}
System.out.println("最大値: " + max);
System.out.println("最小値: " + min);
}
}
ポイント: 最大値・最小値の初期値は配列の最初の要素で設定します。Integer.MAX_VALUE や Integer.MIN_VALUE で初期化する方法もありますが、配列の要素で初期化するほうが自然です。
問題4:配列の逆順出力 ⭐
問題
配列 {10, 20, 30, 40, 50} の要素を逆順に出力してください。
期待する出力
元の配列: 10 20 30 40 50
逆順: 50 40 30 20 10
模範解答
public class Exercise04 {
public static void main(String[] args) {
int[] numbers = {10, 20, 30, 40, 50};
System.out.print("元の配列: ");
for (int i = 0; i < numbers.length; i++) {
if (i > 0) System.out.print(" ");
System.out.print(numbers[i]);
}
System.out.println();
System.out.print("逆順: ");
for (int i = numbers.length - 1; i >= 0; i--) {
if (i < numbers.length - 1) System.out.print(" ");
System.out.print(numbers[i]);
}
System.out.println();
}
}
ポイント: 逆順にループするには i = numbers.length - 1 から i >= 0 まで i-- でデクリメントします。配列の最後のインデックスは length - 1 であることに注意しましょう。
問題5:要素の検索 ⭐⭐
問題
配列 {15, 42, 8, 23, 42, 67, 42, 91} から、値 42 が何回出現するか、またそれぞれ何番目(0始まり)にあるかを出力してください。
期待する出力
検索対象: 42
出現回数: 3回
位置: [1, 4, 6]
模範解答
public class Exercise05 {
public static void main(String[] args) {
int[] numbers = {15, 42, 8, 23, 42, 67, 42, 91};
int target = 42;
System.out.println("検索対象: " + target);
int count = 0;
StringBuilder positions = new StringBuilder("[");
for (int i = 0; i < numbers.length; i++) {
if (numbers[i] == target) {
if (count > 0) {
positions.append(", ");
}
positions.append(i);
count++;
}
}
positions.append("]");
System.out.println("出現回数: " + count + "回");
System.out.println("位置: " + positions);
}
}
ポイント: 線形探索(リニアサーチ)は配列の先頭から順番にチェックする最も基本的な探索方法です。StringBuilder を使うと文字列の結合を効率的に行えます。
問題6:配列のコピーと比較 ⭐⭐
問題
以下の処理を行い、配列のコピーについて理解してください。
- 配列
{1, 2, 3, 4, 5}を作成 - 代入によるコピー(参照コピー)と新しい配列への要素コピーを行う
- コピー元の配列の最初の要素を
99に変更 - 各配列の内容を出力して、違いを確認する
期待する出力
=== コピー元を変更後 ===
コピー元(original): 99 2 3 4 5
参照コピー(refCopy): 99 2 3 4 5
要素コピー(elementCopy): 1 2 3 4 5
模範解答
public class Exercise06 {
public static void main(String[] args) {
int[] original = {1, 2, 3, 4, 5};
// 参照コピー(同じ配列を指す)
int[] refCopy = original;
// 要素コピー(新しい配列を作成)
int[] elementCopy = new int[original.length];
for (int i = 0; i < original.length; i++) {
elementCopy[i] = original[i];
}
// コピー元を変更
original[0] = 99;
// 出力
System.out.println("=== コピー元を変更後 ===");
System.out.print("コピー元(original): ");
for (int n : original) System.out.print(n + " ");
System.out.println();
System.out.print("参照コピー(refCopy): ");
for (int n : refCopy) System.out.print(n + " ");
System.out.println();
System.out.print("要素コピー(elementCopy): ");
for (int n : elementCopy) System.out.print(n + " ");
System.out.println();
}
}
ポイント: Javaでは配列を = で代入すると参照のコピーになり、同じ配列を共有します。独立したコピーを作るには要素を1つずつコピーするか、Arrays.copyOf() を使います。この違いは実務で重要なバグの原因になります。
問題7:バブルソート ⭐⭐
問題
配列 {64, 34, 25, 12, 22, 11, 90} をバブルソートで昇順に並び替え、各ステップの状態を出力してください。
期待する出力
初期状態: [64, 34, 25, 12, 22, 11, 90]
パス1: [34, 25, 12, 22, 11, 64, 90]
パス2: [25, 12, 22, 11, 34, 64, 90]
パス3: [12, 22, 11, 25, 34, 64, 90]
パス4: [12, 11, 22, 25, 34, 64, 90]
パス5: [11, 12, 22, 25, 34, 64, 90]
パス6: [11, 12, 22, 25, 34, 64, 90]
ソート完了: [11, 12, 22, 25, 34, 64, 90]
模範解答
public class Exercise07 {
public static void main(String[] args) {
int[] arr = {64, 34, 25, 12, 22, 11, 90};
System.out.print("初期状態: ");
printArray(arr);
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
// スワップ
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
System.out.print("パス" + (i + 1) + ": ");
printArray(arr);
}
System.out.print("ソート完了: ");
printArray(arr);
}
static void printArray(int[] arr) {
System.out.print("[");
for (int i = 0; i < arr.length; i++) {
if (i > 0) System.out.print(", ");
System.out.print(arr[i]);
}
System.out.println("]");
}
}
ポイント: バブルソートは隣接する要素を比較して交換を繰り返すソートアルゴリズムです。計算量はO(n²)で効率は良くありませんが、ソートの基本概念を理解するのに最適です。実務では Arrays.sort() を使います。
問題8:二次元配列 ⭐⭐
問題
3人の生徒の3科目のテスト結果を二次元配列で管理し、各生徒の合計と平均、および各科目の平均を出力してください。
| 国語 | 数学 | 英語 | |
|---|---|---|---|
| 生徒A | 80 | 70 | 90 |
| 生徒B | 65 | 95 | 75 |
| 生徒C | 90 | 85 | 80 |
期待する出力
=== 成績表 ===
国語 数学 英語 合計 平均
生徒A: 80 70 90 240 80.0
生徒B: 65 95 75 235 78.3
生徒C: 90 85 80 255 85.0
---
科目平均: 78.3 83.3 81.7
模範解答
public class Exercise08 {
public static void main(String[] args) {
int[][] scores = {
{80, 70, 90},
{65, 95, 75},
{90, 85, 80}
};
String[] students = {"生徒A", "生徒B", "生徒C"};
String[] subjects = {"国語", "数学", "英語"};
System.out.println("=== 成績表 ===");
System.out.println(" 国語 数学 英語 合計 平均");
for (int i = 0; i < scores.length; i++) {
int total = 0;
System.out.printf("%s:", students[i]);
for (int j = 0; j < scores[i].length; j++) {
System.out.printf("%6d", scores[i][j]);
total += scores[i][j];
}
double avg = (double) total / scores[i].length;
System.out.printf("%6d%6.1f%n", total, avg);
}
// 科目平均
System.out.println("---");
System.out.print("科目平均:");
for (int j = 0; j < subjects.length; j++) {
int subjectTotal = 0;
for (int i = 0; i < scores.length; i++) {
subjectTotal += scores[i][j];
}
double subjectAvg = (double) subjectTotal / scores.length;
System.out.printf("%6.1f", subjectAvg);
}
System.out.println();
}
}
ポイント: 二次元配列は 配列[行][列] でアクセスします。行ごとの処理(生徒別集計)と列ごとの処理(科目別集計)でループの内外が入れ替わることに注目してください。
問題9:配列の回転 ⭐⭐⭐
問題
配列 {1, 2, 3, 4, 5, 6, 7} を右に k = 3 だけ回転させてください。
回転とは、末尾の要素が先頭に移動する操作です。
期待する出力
回転前: [1, 2, 3, 4, 5, 6, 7]
右に3回転: [5, 6, 7, 1, 2, 3, 4]
ヒント
- 新しい配列を作る方法と、元の配列を直接操作する方法があります
- 新しい位置は
(元のインデックス + k) % 配列の長さで計算できます
模範解答
public class Exercise09 {
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5, 6, 7};
int k = 3;
System.out.print("回転前: ");
printArray(arr);
int[] rotated = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
int newIndex = (i + k) % arr.length;
rotated[newIndex] = arr[i];
}
System.out.print("右に" + k + "回転: ");
printArray(rotated);
}
static void printArray(int[] arr) {
System.out.print("[");
for (int i = 0; i < arr.length; i++) {
if (i > 0) System.out.print(", ");
System.out.print(arr[i]);
}
System.out.println("]");
}
}
ポイント: %(剰余演算子)を使うと、配列の末尾を超えた位置を先頭に戻すことができます。この 循環(サーキュラー) の考え方は、リングバッファなどのデータ構造でも使われます。
問題10:売上分析レポート ⭐⭐⭐
問題
ある店舗の1週間の売上データを配列で管理し、以下の分析レポートを出力してください。
売上データ(単位:万円):{45, 32, 67, 23, 78, 55, 41}
曜日:月〜日
出力する情報:
- 日別の売上(棒グラフ風に
■で表示、1個 = 5万円、端数切り上げ) - 合計売上
- 平均売上(小数第1位まで)
- 最高売上の曜日と金額
- 最低売上の曜日と金額
- 平均以上の日と平均未満の日
期待する出力
=== 週間売上レポート ===
月: ■■■■■■■■■ 45万円
火: ■■■■■■■ 32万円
水: ■■■■■■■■■■■■■■ 67万円
木: ■■■■■ 23万円
金: ■■■■■■■■■■■■■■■■ 78万円
土: ■■■■■■■■■■■ 55万円
日: ■■■■■■■■■ 41万円
---
合計: 341万円
平均: 48.7万円
最高: 金曜日 78万円
最低: 木曜日 23万円
---
平均以上の日: 水 金 土(3日)
平均未満の日: 月 火 木 日(4日)
模範解答
public class Exercise10 {
public static void main(String[] args) {
int[] sales = {45, 32, 67, 23, 78, 55, 41};
String[] days = {"月", "火", "水", "木", "金", "土", "日"};
System.out.println("=== 週間売上レポート ===");
// 日別の棒グラフ表示
for (int i = 0; i < sales.length; i++) {
int barLength = (int) Math.ceil(sales[i] / 5.0);
StringBuilder bar = new StringBuilder();
for (int j = 0; j < barLength; j++) {
bar.append("■");
}
System.out.printf("%s: %-18s %d万円%n", days[i], bar, sales[i]);
}
// 集計
int sum = 0;
int maxIndex = 0;
int minIndex = 0;
for (int i = 0; i < sales.length; i++) {
sum += sales[i];
if (sales[i] > sales[maxIndex]) maxIndex = i;
if (sales[i] < sales[minIndex]) minIndex = i;
}
double average = (double) sum / sales.length;
System.out.println("---");
System.out.println("合計: " + sum + "万円");
System.out.println("平均: " + String.format("%.1f", average) + "万円");
System.out.println("最高: " + days[maxIndex] + "曜日 " + sales[maxIndex] + "万円");
System.out.println("最低: " + days[minIndex] + "曜日 " + sales[minIndex] + "万円");
// 平均以上/未満
System.out.println("---");
StringBuilder aboveAvg = new StringBuilder();
StringBuilder belowAvg = new StringBuilder();
int aboveCount = 0;
int belowCount = 0;
for (int i = 0; i < sales.length; i++) {
if (sales[i] >= average) {
if (aboveCount > 0) aboveAvg.append(" ");
aboveAvg.append(days[i]);
aboveCount++;
} else {
if (belowCount > 0) belowAvg.append(" ");
belowAvg.append(days[i]);
belowCount++;
}
}
System.out.println("平均以上の日: " + aboveAvg + "(" + aboveCount + "日)");
System.out.println("平均未満の日: " + belowAvg + "(" + belowCount + "日)");
}
}
ポイント: 配列とループを組み合わせた総合問題です。データの集計・分析・可視化は実務でも頻出するパターンです。Math.ceil() は切り上げ、printf の %-18s は左寄せ18文字幅の書式指定です。
まとめ
| 問題 | テーマ | 難易度 |
|---|---|---|
| 問題1 | 配列の宣言と出力 | ⭐ |
| 問題2 | 合計と平均 | ⭐ |
| 問題3 | 最大値と最小値 | ⭐ |
| 問題4 | 配列の逆順出力 | ⭐ |
| 問題5 | 要素の検索(線形探索) | ⭐⭐ |
| 問題6 | 配列のコピーと参照 | ⭐⭐ |
| 問題7 | バブルソート | ⭐⭐ |
| 問題8 | 二次元配列(成績表) | ⭐⭐ |
| 問題9 | 配列の回転 | ⭐⭐⭐ |
| 問題10 | 売上分析レポート(総合問題) | ⭐⭐⭐ |
次回は メソッド のコーディング問題です!
シリーズ一覧:Java研修コーディング問題集
- 変数・データ型・演算子 編
- 条件分岐(if / switch)編
- 繰り返し処理(for / while)編
- 👉 配列 編(本記事)
- メソッド 編
- 文字列操作(String)編
- クラスとオブジェクト 編
- 継承とインターフェース 編
- 例外処理 編
- コレクションと Stream API 編
著者: @kotaro_ai_lab
AI駆動開発やテック情報を毎日発信しています。フォローお気軽にどうぞ!