Java | 配列を逆順に並べ替える方法

Java Java
スポンサーリンク

配列の逆順の基本アイデア

はじめは少し戸惑うかもしれないけど、やることはシンプルです。配列の「最初」と「最後」を入れ替え、次に「2番目」と「最後から2番目」を入れ替える——これを中央に向かって繰り返すだけで、逆順になります。


手順をかみ砕いて説明

  • 両端から内側へ動かす:
    • 左からの位置を表す変数を用意します(例: f)。
    • 右からの位置を表す変数も用意します(例: l)。
    • f は 0 から右へ進み、l は 配列の長さ-1 から左へ進みます。
  • 入れ替えのやり方:
    • いきなり上書きすると値が消えるので、一時変数(例: temp)にどちらかを退避してから入れ替えます。
  • いつ止めるか:
    • fl より小さい間だけ入れ替えます。
    • 偶数要素なら中央ですれ違い、奇数要素なら中央の要素は触らずそのままになります。

例題1:整数配列を逆順にする(基本)

import java.util.Arrays;

public class ReverseArrayBasic {
    public static void main(String[] args) {
        int[] src = {12, 24, 18, 31, 17};
        System.out.println("Before: " + Arrays.toString(src)); // [12, 24, 18, 31, 17]

        // 両端から入れ替える
        for (int f = 0, l = src.length - 1; f < l; f++, l--) {
            int temp = src[f];   // 退避
            src[f] = src[l];     // 右端を左へ
            src[l] = temp;       // 退避していた左端を右へ
        }

        System.out.println("After : " + Arrays.toString(src)); // [17, 31, 18, 24, 12]
    }
}
Java
  • ポイント:
    • f < l が止め時。中央に到達したら終わり。
    • temp は値を失わないための「避難所」。
    • f++l-- で、左と右から一歩ずつ近づきます。

例題2:文字列配列も同じ手順でOK

import java.util.Arrays;

public class ReverseStringArray {
    public static void main(String[] args) {
        String[] names = {"Taro", "Hanako", "Ken", "Ami"};
        System.out.println("Before: " + Arrays.toString(names)); // [Taro, Hanako, Ken, Ami]

        for (int f = 0, l = names.length - 1; f < l; f++, l--) {
            String temp = names[f];
            names[f] = names[l];
            names[l] = temp;
        }

        System.out.println("After : " + Arrays.toString(names)); // [Ami, Ken, Hanako, Taro]
    }
}
Java
  • ポイント:
    • 型が String でも考え方は同じ。
    • 参照型でも「退避→入れ替え」の流れは同じです。

別パターン:元の配列を変えずに「逆順のコピー」を作る

import java.util.Arrays;

public class ReverseToNewArray {
    public static void main(String[] args) {
        int[] src = {10, 20, 30, 40, 50};
        int[] dest = new int[src.length];

        // 左から右へ読みつつ、右から左へ書く
        for (int i = 0; i < src.length; i++) {
            dest[src.length - 1 - i] = src[i];
        }

        System.out.println("src : " + Arrays.toString(src));  // [10, 20, 30, 40, 50]
        System.out.println("dest: " + Arrays.toString(dest)); // [50, 40, 30, 20, 10]
    }
}
Java
  • ポイント:
    • dest[length - 1 - i] が「逆側の位置」。
    • 元の配列を壊したくないときに便利。

つまずきポイントと直し方

  • インデックスの範囲外エラー:
    • 原因: l の初期値を length にしてしまう。
    • 対策: 右端は常に length - 1
  • 上書きで値が消える:
    • 原因: 退避せずに代入を連続で行う。
    • 対策: 必ず 一時変数 temp を使う。
  • ループが止まらない/止まるのが早い:
    • 原因: 条件を f <= l にして中央で二度入れ替えしてしまうか、逆に f > l を使ってしまう。
    • 対策: 条件は f < l が安全。
  • 奇数/偶数の中央の扱い:
    • 理解: 奇数長は中央の要素は動かさない、偶数長は中央で入れ替えが終わる。

練習課題(手を動かして慣れる)

  1. 偶数長の配列で検証:
    • 例: {1, 2, 3, 4, 5, 6} を逆順に。
    • 途中で fl の値を System.out.println で出して、動きを追ってみる。
  2. 配列が空/1要素の場合:
    • 例: {}{42} でもコードが落ちないか確認。
    • 期待結果は「そのまま」。
  3. メソッドにする:
    • static void reverse(int[] a) を作って、どの配列にも使えるようにする。
    • 参照渡しなので、呼び出し元の配列が直接入れ替わることも確認。
public static void reverse(int[] a) {
    for (int f = 0, l = a.length - 1; f < l; f++, l--) {
        int temp = a[f];
        a[f] = a[l];
        a[l] = temp;
    }
}
Java

補足:配列以外(リスト)なら簡単に逆順

  • Javaのリストなら:
    • Collections.reverse(list); で一発逆順。
    • ただし、今回学んだ「入れ替えの仕組み」はアルゴリズムの基本なので、配列で手作りする経験が大事。
タイトルとURLをコピーしました