1. 다차원 배열 (Multi- dimension)
1.1 2차원 배열의 선언과 인덱스
2차원 배열은 주로 테이블 형태의 데이터를 담는데 사영되며, 만약 4행 3열의 데이터를 담기위한 배열을 생성하려면 다음과 같이 하면 된다. 2차원 배열의 요소에는 int의 기본값인 0이 저장된다.
int[][] score = new int[4][3]; //4행 3열의 2차원 배열
2차원 배열의 index
2차원 배열은 행(row)과 열(column)으로 구성되어 있어 index도 행과 열에 각각 존재한다.
행index의 범위는 0 ~ 행의 길이-1, 열index의 범위는 0~열의 길이-1 이다.
각 요소에 접근하는 방법은 배열이름[행index][열index]이다.

이렇게 배열을 생성하면 score[0][0] ~ score[3][2] 까지 총 12개의 접근할 수 있다.
1.2 2차원 배열의 초기화
2차원 배열도 괄호를 사용해 생성과 초기화를 동시에 할 수 있다. 다만 1차원 배열보다 괄호{}를 한번 더 써서 행별로 구분해 준다.
int[][] arr = new int[][]{{1,2,3}, {4,5,6}};
int[][] arr2 = {{1,2,3},{4,5,6}};
//보통 보기좋게 이렇게 표현한다.
int[][] arr2 = {
{1, 2, 3},
{4, 5, 6}
};
2차원 배열이 메모리에 어떤 형태로 그려보면 다음과 같다. 배열의 배열로 구성되어 있다.
여기서 score.length는 5이며, score[0].length는 3이다.
int[][] score = {
{100,100,100},
{20,20,20},
{30,30,30},
{40,40,40},
{50,50,50}
};

따라서 모든 요소를 출력하고, 총합을 구할때는 다음과 같이 할 수 있다.
1.3 가변 배열
2차원 이상의 다차원 배열을 생성할 때 전체 배열 차수 중 마지막 차수의 길이를 지정하지 않고, 추후에 각기 다른 길이의 배열을 생성함으로써 고정된 형태가 아닌 유동적인 가변배열을 만들 수 있다.
//5행 3열의 2차원 배열
int[][] score = new int[5][3];
//각 행 마다 다른 길이의 배열 생성도 가능
int[][] score = new int[3][];
score[0] = new int[5];
score[1] = new int[4];
score[2] = new int[1];
1.4 다차원 배열의 활용
1. 좌표에 X표 하기 : 둘이 마주 앉아 다양한 크기의 배를 상대방이 알지 못하게 배치한 다음, 번갈아가며 좌표를 불러가며 상대방의 배의 위치를 알아내는 게임. 0이 바다고 1이 배라고 가정하며, 배의 좌표를 찾을 시 O, 틀릴 시 X를 출력한다.
public static void main(String[] args) {
//입력한 2차원 좌표에 위치에 X 표시하기
final int SIZE = 10;
int x = 0;
int y = 0;
//크키가 10인 문자형 2차원 배열 선언
char[][] board = new char[SIZE][SIZE];
//0이 바다 , 1이 배
byte[][] shipBoard = {
{0, 0, 0, 0, 0, 0, 0, 1, 1},
{0, 0, 0, 0, 0, 0, 0, 1, 1},
{0, 0, 0, 0, 0, 0, 0, 1, 1},
{0, 0, 0, 0, 0, 0, 0, 1, 1},
{0, 0, 0, 0, 0, 0, 0, 1, 1},
{0, 0, 0, 0, 0, 0, 0, 1, 1},
{0, 0, 0, 0, 0, 0, 0, 1, 1},
{0, 0, 0, 0, 0, 0, 0, 1, 1},
{0, 0, 0, 0, 0, 0, 0, 1, 1},
};
//배열 board에 좌표를 쉽게 입력 및 확인하기위해 행번호과 엻번호가 미리 입력한다.
for (int i = 1; i < SIZE; i++) {
board[0][i] = board[i][0] = (char) (i + '0'); //숫자 1에 '0'을 더하면 문자 '1'이 된다.
}
//출력으로 확인가능
// for (char[] tmp : board) {
// System.out.println(Arrays.toString(tmp));
// }
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.printf("좌표를 입력하세요. (종료는 00)>");
String input = scanner.nextLine(); // 화면에서 입력받는 내용을 input에 저장
if (input.length() == 2) {
x = input.charAt(0) - '0'; //문자 '0'을 숫자 0으로 변환
y = input.charAt(1) - '0';
if (x == 0 && y == 0) {
break;
}
}
if (input.length() != 2 || x <= 0 || y <= 0 || x >= SIZE || y >= SIZE) {
System.out.println("잘못된 입력입니다. 다시 입력해주세요");
continue;
}
//삼항연산자 ?를 기준으로 앞이 조건
//1이라면 배, 0이면 바다라는 뜻
board[x][y] = shipBoard[x - 1][y - 1] == 1 ? 'O' : 'X';
//정답인 board 출력
for (int i = 0; i < SIZE; i++) {
System.out.println(board[i]);
}
}
}
2. 빙고 게임 :5X5 크기의 빙고판에 1~ 25의 숫자를 차례로 저장한 다음에, Math.random()을 이용해서 저장된 값의 위치를 섞은 후 , 숫자를 입력해 입력한 숫자가 빙고배열의 숫자와 같으면 0으로 바꾸는 게임
public static void main(String[] args) {
int SIZE = 5;
int tmp, x, y, num = 0;
int[][] bingo = new int[SIZE][SIZE];
Scanner scanner = new Scanner(System.in);
//배열의 요소를 1~ 25로 초기화
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
bingo[i][j] = i * SIZE + j + 1;
}
}
for (int[] arr : bingo) {
System.out.println(Arrays.toString(arr));
}
System.out.println("===============================");
//bingo 배열을 랜덤 숫자를 이용해서 섞기
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
x = (int) (Math.random() * SIZE); //Math.random()은 0.0~ 1.0사이의 double형 숫자를 만들어줌.
y = (int) (Math.random() * SIZE);
//25개의 요소를 모두 바꾸기
tmp = bingo[x][y];
bingo[x][y] = bingo[i][j];
bingo[i][j] = tmp;
}
}
//do - while : do를 먼저 실행한 후 while의 조건문이 맞으면 다시 실행문을 수행하고, 조건이 맞지않으면 빠져나온다.
do {
//현재 빙고 먼저 출력
for (int i = 0; i < SIZE; i++) {
System.out.println(Arrays.toString(bingo[i]));
}
System.out.println("===============================");
//숫자 입력 받기
System.out.printf("숫자를 입력하세요 : ");
num = scanner.nextInt();
outer:
//outer는 라벨. 다중반복문에 이름을 붙인 것
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
if (bingo[i][j] == num) {
bingo[i][j] = 0;
break outer; //다중반복문을 빠져나가기
}
}
}
} while (num != 0);
}
- outer : 코드에서 outer이 나오는데 outer은 일종의 라벨로, 다중반복문에 이름을 붙인 것이다. 따라서 코드상에서 0일 경우 다중반복문인 outer 를 빠져나간다. break 말고도 안쪽 내용을 무시하고 다시 다중반복문을 타고 싶을 경우 continue도 사용할 수 있다.
- do - while : do를 먼저 실행한 후 while의 조건문이 맞으면 다시 실행문을 수행하고, 조건이 맞지않으면 빠져나온다.
3.행렬의 곱셈 : 행렬(maxtrix)에서 두 행렬의 곱셈이 가능하려면, m1의 열의 길이와 m2의 행의 길이가 같아야한다는 조건이 있다. 따라서 2행 3열인 행렬과 3행2열인 행렬을 곱하면 결과는 2행 2열이 된다.
public static void main(String[] args) {
//m1 x m2 = m3 으로 정한다면
int[][] m1 = {
{1, 2, 3},
{4, 5, 6}
};
int[][] m2 = {
{1, 2},
{3, 4},
{5, 6}
};
int ROW = m1.length; // m1의 행 길이 2
int COL = m2[0].length; //m2의 열 길이 2
int M2_ROW = m2.length; // m2의 행 길이 2
int[][] m3 = new int[ROW][COL];
//방법 1
for (int i = 0; i < ROW; i++) {
for (int j = 0; j < COL; j++) {
m3[i][j] = m1[i][0] * m2[0][j]
+ m1[i][1] * m2[1][j]
+ m1[i][2] * m2[2][j];
}
}
//방법1을 확장시켜서 m1의 열 인덱스와 m2의 행 인덱스가 동일하게 증가하므로 이 부분을 for문으로 수정한다면!
for (int i = 0; i < ROW; i++) { //0.1
for (int j = 0; j < COL; j++) {//0.1
for (int k = 0; k < M2_ROW; k++) { //0,1,2
m3[i][j] += m1[i][k] * m2[k][j];
}
}
}
//행렬 곱셈의 결과를 출력
for (int[] tmp : m3) {
System.out.println(Arrays.toString(tmp));
}
}
출처 : 자바의 정석
'Java' 카테고리의 다른 글
[Java] ArrayList (1) | 2023.12.06 |
---|---|
[Java] 컬렉션 프레임워크 (Collection Framework) (1) | 2023.12.06 |
[Java] String 배열 (0) | 2023.12.06 |
[Java] 배열(Array) (1) | 2023.12.06 |
객체지향 설계 5원칙 - SOLID (0) | 2023.02.23 |