학생 점수 배열에서 합계·평균·최고·최저를 구하고 정렬해 상위 3명을 뽑습니다. Arrays.sort가 원본을 바꾸므로 복사본을 정렬합니다.
import java.util.Arrays;
public class GradeReport {
public static void main(String[] args) {
String[] names = {"김민수", "이서연", "박지훈", "최유진", "정우진"};
int[] scores = {78, 92, 65, 88, 95};
int sum = 0, max = scores[0], min = scores[0], maxIdx = 0;
for (int i = 0; i < scores.length; i++) {
sum += scores[i];
if (scores[i] > max) { max = scores[i]; maxIdx = i; }
if (scores[i] < min) min = scores[i];
}
System.out.printf("평균 %.1f / 최고 %d(%s) / 최저 %d%n",
(double) sum / scores.length, max, names[maxIdx], min);
// 출력: 평균 83.6 / 최고 95(정우진) / 최저 65
int[] sorted = scores.clone(); // 원본 보존
Arrays.sort(sorted); // 오름차순
System.out.println("원본: " + Arrays.toString(scores));
System.out.println("정렬: " + Arrays.toString(sorted));
// 출력: 원본: [78, 92, 65, 88, 95]
// 출력: 정렬: [65, 78, 88, 92, 95]
System.out.print("상위 3점: ");
for (int i = sorted.length - 1; i >= sorted.length - 3; i--) {
System.out.print(sorted[i] + " ");
}
System.out.println();
// 출력: 상위 3점: 95 92 88
// 80점 이상 명단: 인덱스로 두 배열 연결
int passCount = 0;
for (int i = 0; i < scores.length; i++) {
if (scores[i] >= 80) passCount++;
}
String[] passed = new String[passCount];
int k = 0;
for (int i = 0; i < scores.length; i++) {
if (scores[i] >= 80) passed[k++] = names[i];
}
System.out.println("80점 이상: " + Arrays.toString(passed));
// 출력: 80점 이상: [이서연, 최유진, 정우진]
}
}행렬 덧셈과 곱셈, 전치를 구현합니다. 곱셈은 3중 반복문이며 A[i][k] * B[k][j]의 인덱스 구조를 익히는 것이 핵심입니다.
import java.util.Arrays;
public class MatrixOps {
static int[][] add(int[][] a, int[][] b) {
int rows = a.length, cols = a[0].length;
int[][] r = new int[rows][cols];
for (int i = 0; i < rows; i++)
for (int j = 0; j < cols; j++)
r[i][j] = a[i][j] + b[i][j];
return r;
}
static int[][] multiply(int[][] a, int[][] b) {
int n = a.length, m = b[0].length, k = b.length;
int[][] r = new int[n][m];
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
for (int x = 0; x < k; x++)
r[i][j] += a[i][x] * b[x][j];
return r;
}
static int[][] transpose(int[][] a) {
int[][] t = new int[a[0].length][a.length];
for (int i = 0; i < a.length; i++)
for (int j = 0; j < a[0].length; j++)
t[j][i] = a[i][j];
return t;
}
public static void main(String[] args) {
int[][] a = {{1, 2}, {3, 4}};
int[][] b = {{5, 6}, {7, 8}};
System.out.println(Arrays.deepToString(add(a, b)));
// 출력: [[6, 8], [10, 12]]
System.out.println(Arrays.deepToString(multiply(a, b)));
// 출력: [[19, 22], [43, 50]]
System.out.println(Arrays.deepToString(transpose(new int[][]{{1, 2, 3}, {4, 5, 6}})));
// 출력: [[1, 4], [2, 5], [3, 6]]
// 행별 출력
for (int[] row : multiply(a, b)) {
for (int v : row) System.out.printf("%4d", v);
System.out.println();
}
// 출력: 19 22
// 출력: 43 50
}
}영화관 좌석을 boolean 배열로 관리합니다. 예약, 취소, 빈 좌석 수, 연속 빈 좌석 찾기를 구현합니다.
public class SeatMap {
static final int ROWS = 4, COLS = 6;
static boolean[][] seats = new boolean[ROWS][COLS]; // 기본값 false = 빈 좌석
static boolean reserve(int r, int c) {
if (r < 0 || r >= ROWS || c < 0 || c >= COLS) {
System.out.println("잘못된 좌석: " + r + "," + c);
return false;
}
if (seats[r][c]) {
System.out.println("이미 예약됨: " + (char) ('A' + r) + (c + 1));
return false;
}
seats[r][c] = true;
return true;
}
static int countEmpty() {
int n = 0;
for (boolean[] row : seats)
for (boolean taken : row)
if (!taken) n++;
return n;
}
// 같은 행에 k개 연속 빈 좌석의 시작 위치 찾기. 없으면 null
static int[] findConsecutive(int k) {
for (int r = 0; r < ROWS; r++) {
int run = 0;
for (int c = 0; c < COLS; c++) {
run = seats[r][c] ? 0 : run + 1;
if (run == k) return new int[]{r, c - k + 1};
}
}
return null;
}
static void print() {
for (int r = 0; r < ROWS; r++) {
System.out.print((char) ('A' + r) + " ");
for (int c = 0; c < COLS; c++) System.out.print(seats[r][c] ? "X " : "O ");
System.out.println();
}
}
public static void main(String[] args) {
reserve(0, 0); reserve(0, 1); reserve(1, 3);
reserve(0, 0); // 출력: 이미 예약됨: A1
reserve(9, 9); // 출력: 잘못된 좌석: 9,9
print();
// 출력: A X X O O O O
// 출력: B O O O X O O
// 출력: C O O O O O O
// 출력: D O O O O O O
System.out.println("빈 좌석: " + countEmpty()); // 출력: 빈 좌석: 21
int[] pos = findConsecutive(4);
System.out.println("4연석 시작: " + (char) ('A' + pos[0]) + (pos[1] + 1));
// 출력: 4연석 시작: A3
}
}원시 배열, 2차원 배열, 객체 배열에서 복사가 어떻게 다른지 직접 확인합니다.
import java.util.Arrays;
public class CopyDemo {
public static void main(String[] args) {
// 1. 원시 타입 1차원: clone은 완전 독립
int[] a = {1, 2, 3};
int[] b = a.clone();
b[0] = 99;
System.out.println(a[0] + " " + b[0]); // 출력: 1 99
// 2. 대입은 복사가 아님
int[] c = a;
c[0] = 77;
System.out.println(a[0]); // 출력: 77
// 3. 2차원: clone은 얕은 복사
int[][] m = {{1, 2}, {3, 4}};
int[][] shallow = m.clone();
shallow[0][0] = 99;
System.out.println(m[0][0]); // 출력: 99 (안쪽 공유)
System.out.println(m[0] == shallow[0]); // 출력: true
// 4. 깊은 복사
int[][] deep = new int[m.length][];
for (int i = 0; i < m.length; i++) deep[i] = m[i].clone();
deep[1][1] = -1;
System.out.println(Arrays.deepToString(m)); // 출력: [[99, 2], [3, 4]]
System.out.println(Arrays.deepToString(deep)); // 출력: [[99, 2], [3, -1]]
// 5. copyOf로 확장 — ArrayList가 내부적으로 하는 일
int[] grown = Arrays.copyOf(a, 5);
System.out.println(Arrays.toString(grown)); // 출력: [77, 2, 3, 0, 0]
// 6. System.arraycopy: 기존 배열 일부에 덮어쓰기
int[] dst = new int[6];
Arrays.fill(dst, -1);
System.arraycopy(a, 0, dst, 2, 3); // a[0..3) → dst[2..5)
System.out.println(Arrays.toString(dst)); // 출력: [-1, -1, 77, 2, 3, -1]
// 7. 내용 비교
System.out.println(a == a.clone()); // 출력: false
System.out.println(Arrays.equals(a, a.clone())); // 출력: true
}
}분기마다 월 수가 다르다고 가정한 가변 배열과, 임의 개수 인자를 받는 varargs를 함께 씁니다.
import java.util.Arrays;
public class SalesReport {
static long total(long... amounts) { // 가변 인자 → long[]
long s = 0;
for (long a : amounts) s += a;
return s;
}
public static void main(String[] args) {
// 부서별 매출: 부서마다 지점 수가 다름 (가변 배열)
long[][] sales = new long[3][];
sales[0] = new long[]{1_200_000, 980_000}; // 부서 0: 지점 2개
sales[1] = new long[]{2_100_000, 1_750_000, 1_900_000, 800_000}; // 부서 1: 지점 4개
sales[2] = new long[]{3_300_000}; // 부서 2: 지점 1개
long grand = 0;
for (int d = 0; d < sales.length; d++) {
long deptTotal = total(sales[d]); // 배열을 varargs에 그대로 전달
grand += deptTotal;
System.out.printf("부서 %d (%d개 지점): %,d원%n", d, sales[d].length, deptTotal);
}
System.out.printf("총합: %,d원%n", grand);
// 출력: 부서 0 (2개 지점): 2,180,000원
// 출력: 부서 1 (4개 지점): 6,550,000원
// 출력: 부서 2 (1개 지점): 3,300,000원
// 출력: 총합: 12,030,000원
System.out.println(total()); // 출력: 0
System.out.println(total(10, 20, 30)); // 출력: 60
System.out.println(Arrays.deepToString(sales));
// 출력: [[1200000, 980000], [2100000, 1750000, 1900000, 800000], [3300000]]
}
}