ユーザー入力で 3D 配列(層 × 行 × 列) を作り、いくつかの集計(層ごとの合計・平均、全体の合計・平均)と可視化(層ごとの表表示)を行う 完全なコンソールアプリ(Scanner 使用) を用意しました。
このプログラムは 「全ての層が同じサイズにする(uniform)」 か 「行や列を層ごとに自由に決める(jagged)」 を選べます。初心者向けに入力チェック、ヘルプコメント、出力の見やすさも配慮しています。
完全コード(Java)
import java.util.InputMismatchException;
import java.util.Scanner;
public class ThreeDArrayApp {
public static void main(String[] args) {
try (Scanner sc = new Scanner(System.in)) {
System.out.println("=== 3D 配列ミニアプリ ===");
System.out.println("使い方: 層(layer)ごとに数値を入力して、集計・表示します。");
// 1) ユーザーが uniform (同じサイズ) か jagged (行/列可変) か選ぶ
boolean uniform = askYesNo(sc, "全ての層で同じ行数・列数にしますか? (y/n): ");
int layers = readInt(sc, "層 (layers) の数を入力してください(正の整数): ", 1, Integer.MAX_VALUE);
int[][][] arr;
if (uniform) {
int rows = readInt(sc, "各層の行数 (rows) を入力してください(正の整数): ", 1, Integer.MAX_VALUE);
int cols = readInt(sc, "各行の列数 (cols) を入力してください(正の整数): ", 1, Integer.MAX_VALUE);
arr = new int[layers][rows][cols];
// 値の入力(層・行・列ごと)
System.out.println("--- 値を入力してください(整数) ---");
for (int l = 0; l < layers; l++) {
System.out.println("Layer " + l + " の入力:");
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
arr[l][r][c] = readInt(sc, " a[" + l + "][" + r + "][" + c + "] = ", Integer.MIN_VALUE, Integer.MAX_VALUE);
}
}
}
} else {
// jagged: 各層ごとに行数・各行ごとに列数を指定
arr = new int[layers][][];
System.out.println("--- 各層のサイズを入力してください(ジャグ配列) ---");
for (int l = 0; l < layers; l++) {
System.out.println("Layer " + l + " の設定:");
int rows = readInt(sc, " 行数 (rows) を入力(正の整数): ", 1, Integer.MAX_VALUE);
arr[l] = new int[rows][];
for (int r = 0; r < rows; r++) {
int cols = readInt(sc, " row " + r + " の列数 (cols) を入力(正の整数): ", 1, Integer.MAX_VALUE);
arr[l][r] = new int[cols];
}
}
// 値の入力
System.out.println("--- 値を入力してください(整数) ---");
for (int l = 0; l < layers; l++) {
System.out.println("Layer " + l + " の入力:");
for (int r = 0; r < arr[l].length; r++) {
for (int c = 0; c < arr[l][r].length; c++) {
arr[l][r][c] = readInt(sc, " a[" + l + "][" + r + "][" + c + "] = ", Integer.MIN_VALUE, Integer.MAX_VALUE);
}
}
}
}
// データ入力完了 -> 集計・表示
System.out.println("\n=== 入力完了:集計と表示 ===");
printAllLayersAscii(arr);
computeAndPrintSummaries(arr);
System.out.println("=== 終了 ===");
} catch (Exception e) {
System.err.println("予期せぬエラーが発生しました: " + e.getMessage());
e.printStackTrace();
}
}
// ユーティリティ: 整数入力(範囲チェック付き)
private static int readInt(Scanner sc, String prompt, int min, int max) {
while (true) {
try {
System.out.print(prompt);
int v = sc.nextInt();
sc.nextLine(); // consume end-of-line
if (v < min || v > max) {
System.out.println("入力が範囲外です。 " + min + " ~ " + max + " の値を入力してください。");
continue;
}
return v;
} catch (InputMismatchException ime) {
System.out.println("整数を入力してください。");
sc.nextLine(); // consume bad token
}
}
}
// 簡単な yes/no 入力
private static boolean askYesNo(Scanner sc, String prompt) {
while (true) {
System.out.print(prompt);
String line = sc.nextLine().trim().toLowerCase();
if (line.equals("y") || line.equals("yes") || line.equals("はい") || line.equals("y\n")) return true;
if (line.equals("n") || line.equals("no") || line.equals("いいえ") || line.equals("n\n")) return false;
System.out.println("y/yes/はい または n/no/いいえ で答えてください。");
}
}
// 層ごとに ASCII 表示する(2次元表示を層ごとに出す)
private static void printAllLayersAscii(int[][][] arr) {
for (int l = 0; l < arr.length; l++) {
System.out.println("\n--- Layer " + l + " ---");
if (arr[l] == null || arr[l].length == 0) {
System.out.println("(この層は空です)");
continue;
}
// 列幅自動調整:各列ごとの最大桁数を求める(ジャグ対応でまず最大列数を取得)
int maxCols = 0;
for (int r = 0; r < arr[l].length; r++) {
if (arr[l][r] != null && arr[l][r].length > maxCols) maxCols = arr[l][r].length;
}
int[] colWidths = new int[maxCols];
// 各列 j に対して行 r を走査して最大幅を求める(その行に列がなければ無視)
for (int j = 0; j < maxCols; j++) {
int w = 0;
for (int r = 0; r < arr[l].length; r++) {
if (arr[l][r] != null && arr[l][r].length > j) {
int len = String.valueOf(arr[l][r][j]).length();
if (len > w) w = len;
}
}
colWidths[j] = w;
}
// 横線出力
Runnable printLine = () -> {
for (int j = 0; j < maxCols; j++) {
System.out.print("+");
int w = colWidths[j];
for (int k = 0; k < w + 2; k++) System.out.print("-");
}
System.out.println("+");
};
// 表示
for (int r = 0; r < arr[l].length; r++) {
printLine.run();
if (arr[l][r] == null || arr[l][r].length == 0) {
// 空行扱い
System.out.print("| ");
System.out.print("(empty)");
System.out.println();
continue;
}
for (int j = 0; j < arr[l][r].length; j++) {
String val = String.valueOf(arr[l][r][j]);
System.out.print("| " + padRight(val, colWidths[j]) + " ");
}
// if this row has fewer cols than maxCols, print empty cells
for (int j = arr[l][r].length; j < maxCols; j++) {
System.out.print("| " + padRight("", colWidths[j]) + " ");
}
System.out.println("|");
}
printLine.run();
}
}
// 右パディング
private static String padRight(String s, int width) {
StringBuilder sb = new StringBuilder(s == null ? "" : s);
while (sb.length() < width) sb.append(' ');
return sb.toString();
}
// 各種集計(層ごとの合計/平均・全体の合計/平均)
private static void computeAndPrintSummaries(int[][][] arr) {
long grandTotal = 0;
long grandCount = 0;
System.out.println("\n--- Summaries ---");
for (int l = 0; l < arr.length; l++) {
long layerTotal = 0;
long layerCount = 0;
if (arr[l] != null) {
for (int r = 0; r < arr[l].length; r++) {
if (arr[l][r] != null) {
for (int c = 0; c < arr[l][r].length; c++) {
layerTotal += arr[l][r][c];
layerCount++;
}
}
}
}
grandTotal += layerTotal;
grandCount += layerCount;
double layerAvg = layerCount == 0 ? Double.NaN : (double) layerTotal / layerCount;
System.out.printf("Layer %d: total = %d, count = %d, average = %s%n",
l, layerTotal, layerCount,
layerCount == 0 ? "(n/a)" : String.format("%.4f", layerAvg));
}
double grandAvg = grandCount == 0 ? Double.NaN : (double) grandTotal / grandCount;
System.out.println();
System.out.printf("All layers: total = %d, count = %d, average = %s%n",
grandTotal, grandCount,
grandCount == 0 ? "(n/a)" : String.format("%.4f", grandAvg));
}
}
Java使い方メモ
- 上のコードを
ThreeDArrayApp.javaとして保存します。 - ターミナル(コマンドプロンプト)でコンパイル:
javac ThreeDArrayApp.java - 実行:
java ThreeDArrayApp - プロンプトに従って
y/nや整数を入力してください。
プログラムのポイント(初心者向け補足)
uniformを選ぶと全層が同じrows×colsになります。jaggedを選ぶと、各層ごとに行数・各行ごとに列数を自由に設定できます(配列の列数がばらばらな「ジャグ配列」を扱える)。- 入力チェックを入れているので、整数以外を入れても再入力を促します。
printAllLayersAsciiメソッドは層ごとに2次元表を ASCII で整形して表示します。見やすさのため各列の幅を自動調整します。computeAndPrintSummariesでは層ごとの合計・平均と、全体の合計・平均を出します。
