관리 메뉴

나구리의 개발공부기록

자바의 정석 기초편 ch5 - 18 ~ 24[2차원 배열, 2차원배열 예제, Arrays로 배열 다루기] 본문

유튜브 공부/JAVA의 정석 기초편(유튜브)

자바의 정석 기초편 ch5 - 18 ~ 24[2차원 배열, 2차원배열 예제, Arrays로 배열 다루기]

소소한나구리 2023. 11. 13. 17:19

1) 2차원 배열

  • 테이블 형태의 데이터를 저장하기 위한 배열 (일반 표와 같은 데이터)
  • 1차원배열이 여러개 모인 것이 2차원 배열 (1차원 배열의 배열)
  • 3차원 배열은 2차원 배열이 여러개 모인 것
// 4행 3열의 2차원 정수배열을 생성
// score[0][0] ~ score[3][2] 까지의 2차원 배열
int[][] score = new int[4][3]; 

score[0][0] = 100; // 배열 score의 1행 1열에 100을 저장
System.out.println(score[0][0]); // 배열 score의 1행 1열의 값을 출력 -> 100

 

(1) 2차원 배열의 index

  • 앞의 []가 행의 index번호고 뒤의 []가 열의 index 번호를 뜻함
  • 마찬가지로 index 번호는 0부터 시작하므로 헷갈리지 않도록 주의

int[][] score = new int[4][3] 의 Index번호


2) 2차원 배열의 초기화

(1) 2차원 배열 선언 및 초기화 방법

  • {{값1,... 값n}, {값1, ... 값n}, ... } 처럼 초기화 할 수 있음
  • 1자로 초기화를 해도 문제는 없으나 가독성을 위해 행과 열을 구분짓는 것을 권장함
int[][] arr = {{1,2,3},{4,5,6}};	// 1차원 배열처럼 new int[][] 생략 가능

// 다만,가독성을위해 아래처럼 초기화를 권장
int[][] arr = {
                {1,2,3},
                {4,5,6}
              };
  • 1차 배열과 마찬가지로 배열생성과 초기화를 따로따로 할 수 있음

 

(2) 2차원 배열 예시 

  • 2차원 배열이 생성되면 아래의 이미지처럼 표의 형태로 입력된다고 이해하면 됨

  • 메모리구조로 설명하면 1차원 배열로 이루어진 각 행에 또다른 1차원 배열이 생성되어있는 구조라고 접근하면 편함
  • 2차원 배열변수 score의 참조값이 0x100이라고 가정한다면 1차원 배열의 각 행마다(score[0] ~ score[5]) 1차원 배열이 하나더 생성되어 각행마다의 참조값도 0x200, 0x300 ...  처럼 별도로 각각 가지고 있으며 이러한 형태로 2차원 배열 구조를 이룸

(3) 배열의 각 요소를 더하기

  • 2중 반복문을 사용하여 2차 배열의 값을 전부 더해서 출력
  • 2차배열 변수의 길이를 바로 꺼내면 행의 길이를, 2차배열변수의 각행의 길이를 꺼내면 열의 길이를 반환할 수 있음
public static void main(String[] args) {
    int[][] score = {
                      {100, 100, 100},
                      {20, 20, 20},
                      {30, 30, 30},
                      {40, 40, 40},
                    };
    int sum = 0;

    // score[0][0] ~ score[3][2] 까지 순차적으로 반복하는 2중 반복문
    // score.lenth로 행의 길이를 꺼냄
    for (int i = 0; i<score.length; i++) {
    
        // score[i].length로 각 행의 참조가 가르키는 각 1차 배열의 길이를 꺼냄
        for (int j = 0; j<score[i].length; j++) {
       
            System.out.printf("score[%d][%d]=%d%n",i,j,score[i][j]);
            sum += score[i][j];
        }
    }
    System.out.println("sum="+sum);
}

출력
score[0][0]=100
score[0][1]=100
score[0][2]=100
score[1][0]=20
score[1][1]=20
score[1][2]=20
score[2][0]=30
score[2][1]=30
score[2][2]=30
score[3][0]=40
score[3][1]=40
score[3][2]=40
sum=570

 

(4) 과목별 총점 및 평균 구하기

  • 반복문으로 2차 배열 중 특정열의 인덱스 번호를 지정하면 특정 열의 값만 꺼낼 수 있음
public class ex5_9 {
	public static void main(String[] args) {
		int[][] score = {
			              {100, 100, 100},
			              {20, 20, 20},
			              {30, 30, 30},
			              {40, 40, 40},
			              {50, 50, 50},
	                	};
		int korTotal = 0, engTotal = 0, mathTotal = 0;
		
		System.out.println("번호  국어  영어  수학  총점  평균");
		System.out.println("=============================");
		
		for (int i = 0; i<score.length; i++) {
			int sum = 0;		// 개인별	총점
			float avg = 0.0f;	// 개인별 평균
			
			korTotal += score[i][0];
			engTotal += score[i][1];
			mathTotal += score[i][2];
			System.out.printf("%3d", i+1);	// 번호 출력(index+1)
			
			for (int j = 0; j<score[i].length; j++) { 
				sum += score[i][j];
				System.out.printf("%5d", score[i][j]);
			}
			avg = sum/(float)score[i].length;	// 평균 구하기
			System.out.printf("%5d %5.1f%n", sum, avg);
		}
		System.out.println("=============================");
        // 국어, 영어, 수학 점수의 총점
		System.out.printf("총점: %3d %4d %4d%n", korTotal, engTotal, mathTotal);
	}
}

출력
번호  국어  영어  수학  총점  평균
=============================
  1  100  100  100  300 100.0
  2   20   20   20   60  20.0
  3   30   30   30   90  30.0
  4   40   40   40  120  40.0
  5   50   50   50  150  50.0
=============================
총점: 240  240  240

 

(5) 영어단어의 뜻을 맞추는 코드

  • 2차원 배열로 0번 인덱스의 열에는 영단어를, 1번 인덱스의 열에는 뜻을 입력하여 영단어를 보여주고 뜻을 맞추는 프로그램
  • String 클래스의 equals()를 활용하여 입력값과 2차원 배열의 1번 인덱스의 값을 비교하여 같으면 정답처리하고 틀리면 오답 처리함
import java.util.Scanner;

public class ex5_10 {
	public static void main(String[] args) {
		String[][] words = {
			                 {"chair","의자"},      // words[0][0], words[0][1]
                  		  	 {"computer","컴퓨터"},  // words[1][0], words[1][1]
	           		         {"integer","정수"}     // words[2][0], words[2][1]
		                   };

		Scanner scanner = new Scanner(System.in);

		for(int i=0;i<words.length;i++) {
			// %d: 정수형태로 출력, %s: 문자열 형태로 출력
			System.out.printf("Q%d. %s의 뜻은?", i+1, words[i][0]);

			String tmp = scanner.nextLine();

			if(tmp.equals(words[i][1])) {
				System.out.printf("정답입니다.%n%n");
			} else {
			   System.out.printf("틀렸습니다. 정답은 %s입니다.%n%n",words[i][1]);
			}
		} // for문 종료
	} // main메서드 종료
}

출력결과
Q1. chair의 뜻은?의자
정답입니다.

Q2. computer의 뜻은?컴퓨터
정답입니다.

Q3. integer의 뜻은?의자
틀렸습니다. 정답은 정수입니다.

3) Arrays클래스로 배열 다루기

(1) Arrays.equals()

  • 1차원 배열의 값을 비교할 때 사용
  • 2차원 배열의 값을 비교할 때는 deepEquals()를 사용

(2) Arrays.toString()

  • 1차원 배열의 값을 출력할 때 사용
  • 2차원 배열의 값을 출력할 때는 deepToString()를 사용
  • [ ]의 대괄호로 감싸서 값이 출력되며, 2차원 배열은 [[값1, ... , 값n], [값1, ... , 값n], ... ]의 형태로 출력됨
int[] arr = {0,1,2,3,4};
int[][] arr2D = {{11,12},{21,22}};

System.out.println(Arrays.toString(arr)); // [0,1,2,3,4] 출력
System.out.println(Arrays.deepToString(arr2D)); // [[11,12],[21,22]] 출력

String[][] str2D = {{"aaa","bbb"},{"AAA","BBB"}};
String[][] str2D2 ={{"aaa","bbb"},{"AAA","BBB"}};

System.out.println(str2D == str2D2);	// false - 참조변수값(메모리 주소값)을 비교

// false - 2차원 배열인데 1차원 배열의 값을 비교하는 equals를 사용하여 열에해당하는 값이 참조값이 비교됨
System.out.println(Arrays.equals(str2D, str2D2)); 

// true - deepEquals로 다차원 배열의 값을 비교
System.out.println(Arrays.deepEquals(str2D, str2D2));

 

 

(3) 배열의 복사 - Arrays.copyOf(), Arrays.copyOfRange()

  • 1차원 배열을 복사할 때는 copyOf()를, copyOfRange()를 사용
  • copyOf()는 복사할 대상의 0번째 인덱스부터 복사를 해야하지만 copyOfRange()는 복사를 시작할 위치를 지정할 수 있음
  • argument의 복사할 요소의 갯수를 지정하여 원하는 값을 복사할 수 있고, 배열의 길이보다 더 큰값을 지정하면 초과된 index에는 각 배열의 타입의 기본값이 초기화 됨(int배열의 경우 0, 객체배열일 경우 null 등)
  • Arrays 클래스에는 2차원 배열의 복사를 지원하는 메서드는 없어서 직접 구현해야함
int[] arr = {0,1,2,3,4};

// Arrays.copyOf(배열변수,복사할 요소의 갯수)

int[] arr2 = Arrays.copyOf(arr, arr.length);	// arr2=[0,1,2,3,4] 배열 전체 복사
int[] arr3 = Arrays.copyOf(arr, 3);             // arr3=[0,1,2]
int[] arr4 = Arrays.copyOf(arr, 7);          	// arr4=[0,1,2,3,4,0,0]

// Arrays.copyOfRange(배열변수,from,to), from ~ to까지, to는 미포함

int[] arr5 = Arrays.copyOfRange(arr, 2, 4);	// arr5에 [2,3]이 저장됨
int[] arr6 = Arrays.copyOfRange(arr, 0, 7);	// arr6에 [0,1,2,3,4,0,0]이 저장됨

 

 

(4) 배열의 정렬 - Arrays.sort()

  • 배열의 값이 오름차순으로 정렬되며 문자의 경우 아스키코드의 값을 기준으로 정렬됨
  • sort(배열변수, from, to)처럼 argument값을 지정하면 특정 인덱스 범위의 값만 정렬할 수도 있음(to는 미포함)
  • 내림차순은 11장에서 배울 예정(다소 복잡한 설명이 추가됨)
  • 객체 배열의 정렬도 가능하지만 인터페이스를 배워야하므로 뒤에서 다룸
int[] arr10 = {3,2,0,1,4}; // 정렬되지 않은 1차원 배열
Arrays.sort(arr10);        // arr10 배열을 오름차순으로 정렬
System.out.println(Arrays.toString(arr10));	// [0,1,2,3,4], 정렬된 배열을 출력

 

 

 

 

 

** 출처 : 남궁성의 정석코딩_자바의정석