[JAVA] 배열(Array) 정리 - (2)

DongGyu Jung·2022년 1월 6일
1

자바(JAVA)

목록 보기
7/60
post-thumbnail

🏃‍♂️ 들어가기 앞서..

본 게시물은 스터디 활동 중에 작성한 게시물로 자바의 정석-기초편 교재를 학습하여 정리하는 글입니다.
※ 스터디 Page : 〔투 비 마스터 : 자바〕

*해당 교재의 목차 순서와 구성 내용을 기준으로 작성하며
부족할 수 있는 내용은 추가적인 검색을 통해 채워나갈 예정입니다.



배열 부분을 정리하다보니 양이 너무 방대해져서
의도치 않게 두 개의 글로 나누게 되었습니다.
(배열 정리 ① 참고)

※ 2차원 배열

이번엔 그냥 배열이 아닌
우리가 앞서 보았던 1차원 배열이 아닌

" 2차원 이상의 배열, 다차원 배열(multi-dimensional) "에 대해
알아보도록 하자.

차원의 단계에는 메모리 용량이 감당하는 한 제한이 없지만..
주로 1차원2차원 배열이 사용되니
우선 2차원 배열에 대해 알아보도록 하자.

◎ 선언

선언 방법은 단순하다.
1차원 배열 선언방법과 동일한데
대괄호[]가 하나 더 붙는다고 생각하면 된다.

  • 타입[][] 변수이름 ; 의 형식

  • 타입 변수이름 [][]; 의 형식

  • 타입[] 변수이름[] ; 의 형식

위 3가지의 형식으로 선언이 가능하다.

참고로 2차원 배열은
주로 테이블(Table) 데이터를 담는데 사용되고
위 저 형식에서
첫 번째 []는 테이블 데이터의 행(row) 값이고
두 번째 []는 테이블 데이터의 열(column) 값이다.

int[][] score = new int[4][3] ; // 4행 3열의 2차원 배열

당연히 이 예제는 int타입의 배열이니
기본값은 0이 되겠다.

◎ 인덱스

인덱스는
위에 설명한대로
의 개념으로 접근하면 되고

범위는 당연히
0부터 시작이며
끝 값은 [각 배열의 길이] - 1 이다.

int[][] score = new int[4][3] // 4행 3열의 2차원 배열

score[0][0] = 100 ; // 2차원 배열 score의 1행 1열값을 100으로
System.out.println(score[0][0]) // 100 출력 (1행 1열 값)

◎ 초기화

초기화 또한
기존에 알아봤던 1차원 배열의 경우와 비슷한데
{}안에 {}이 더 있다고 보면 된다.
( 심지어, new int가 생략되는 경우와 생략이 불가능한 코드 구성 조건도 동일하다. )

int[][] arr = new int[][]{ {1, 2, 3} , {4, 5, 6} };
int[][] arr = { {1, 2, 3} , {4, 5, 6} }; //생략이 가능하며
// 선언과 동시에 생성 하지 않는 이상 생략 불가능하다는 것도 동일하다.

/*
필수나 오류 발생은 아니지만
가독성과 이해가 쉬우려면 아래 형식과 같이 작성하는 것이 좋다.
*/
int[][] arr = {
		{1, 2, 3}, // 1행
        	{4, 5, 6}  // 2행
              };

여기서 잠깐
문득 궁금증이 생긴다.
이렇게 2차원 배열이 생긴다면 길이, 즉 .length은 어떻게 출력될까?

우선 행과 열의 수가 다른 배열을 하나 만들고 출력해보자

public static void main(String[] args) {
        int[][] score = {
                {100, 100, 100},
                {70, 80, 90},
                {65, 85, 93},
                {100, 75, 60}
        };
        int tsum = 0; // 배열 내 모든 값의 합
        int rsum = 0; // 각 행의 합을 나타내기 위한 변수

        for (int i = 0; i < score.length; i++) { // (2차원배열).length = 행(row) 수 -> 4회 반복
            for (int k = 0; k < score[i].length; k++) { // (2차원배열)[( row index) ].length = 열(column) 수 -> 3회 반복
                System.out.printf("score[%d][%d] (%d행 %d열) = %d %n", i,k, i+1, k+1, score[i][k]) ;
                rsum += score[i][k];
                tsum += score[i][k];
            }
            System.out.printf("score[%d] (%d행) 합 = %d %n", i, i+1, rsum);
            rsum = 0; // 행마다 0으로 초기화
            System.out.println(); // 행 정보 출력마다 빈 줄 간격
        }
        System.out.println("배열 내 총 합 = "+tsum) ;
    }
    
score[0][0] (11) = 100 
score[0][1] (12) = 100 
score[0][2] (13) = 100 
score[0] (1)= 300 

score[1][0] (21) = 70 
score[1][1] (22) = 80 
score[1][2] (23) = 90 
score[1] (2)= 240 

score[2][0] (31) = 65 
score[2][1] (32) = 85 
score[2][2] (33) = 93 
score[2] (3)= 243 

score[3][0] (41) = 100 
score[3][1] (42) = 75 
score[3][2] (43) = 60 
score[3] (4)= 235 

배열 내 총 합 = 1018

2차원 배열 참조 함수 에 대한 .length : 행(row)의 수
내부 구성 1차원 배열 에 대한 .length : 열(column)의 수

{ 활용 }

예제를 보면서
활용하는 방법에 대해 알아보자.

① 총합 & 평균

public static void main(String[] args) {
        int[][] score = { // 5행 3열 Table형 2차원 배열 생성
                {100, 100, 100},
                {70, 80, 90},
                {65, 85, 93},
                {100, 75, 60},
                {50, 50, 50}
        };
        int korSum = 0, engSum = 0, mathSum = 0 ;

        System.out.println("번호  국어  영어  수학  총점  평균");
        System.out.println("==============================");

        for (int i = 0; i < score.length; i++){
            int sum = 0; // 개인별(행별) 총점
            float avg = 0.0f; // 개인별(행별) 평균

            korSum += score[i][0] ;
            engSum += score[i][1] ;
            mathSum += score[i][2] ;
            System.out.printf("%3d", i+1) ; // 순번(행번호) _ 3으로 길이 지정 -> 남는 공간 공백 만들어 출력

            for (int k = 0; k < score[i].length; k++) {
                sum += score[i][k]; // 행별 총점 변수에 각 배열의 각 값들을 누적합
                System.out.printf("%5d", score[i][k]); // 각 값들을 출력 _ %n은 빼서 이어붙여 출력 (%5 길이 지정)
            }
            avg = sum/(float)score[i].length;
            System.out.printf("%5d %5.1f %n", sum, avg); // 각 값 대상 for문 마치고 총합 평균 출력
        }
        System.out.println("==============================");
        System.out.printf("총점 : %3d %4d %4d %n", korSum, engSum, mathSum) ;
    }
 


번호  국어  영어  수학  총점  평균
==============================
  1  100  100  100  300 100.0 
  2   70   80   90  240  80.0 
  3   65   85   93  243  81.0 
  4  100   75   60  235  78.3 
  5   50   50   50  150  50.0 
==============================
총점 : 385  390  393 

앞서 먼저 해보았던 출력 코드를 조금 더 응용해서
평균 값까지 출력했으며
더 깔끔하게 출력되게끔 만들었다.

② String 문자열 2차원 배열

public static void main(String[] args) {
	// 앞서 살펴보았던 정수 2차원 배열과 사용하는 방법은 동일하다
        String[][] words = {
                {"chair", "의자"},
                {"bed", "침대"},
                {"book", "책"},
                {"integer", "정수"}
        };

        Scanner scanner = new Scanner(System.in) ; // 질문응답 형식 프로그램

        for (int i = 0; i < words.length; i++) {
            System.out.printf("질문%d . %s의 뜻은?", i+1, words[i][0]) ; // .printf()를 활용해 %s로 문자열 출력

            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]);
            }
        }
    }
    
질문1 . chair의 뜻은?의자
정답! 

질문2 . bed의 뜻은?의자
오답! (정답 : 침대) 

질문3 . book의 뜻은?책
정답! 

질문4 . integer의 뜻은?실수
오답! (정답 : 정수) 


🔨 간단히 알아보는 《Arrays 클래스

비교 & 출력 - equals() | toString()

앞선 1차원 배열 정리할 때도 사용해보았지만
.toString()메서드로 값들을 문자열로서 배열 형태로 한 줄을 출력해 줄 수 있는데
단, 일차원 배열에만 사용 가능하니 주의해야 한다.
(.toString() 2차원 배열.ver = deepToString() : 모든 요소에 재귀적 접근을 하기 때문에 차원에 한계 X)

int[] arr1 = {1, 2, 3} ;
int[][] arr2 = { {1, 2, 3} , {4, 5, 6} };

System.out.println(Arrays.toString(arr1)); // [1, 2, 3]
System.out.println(Arrays.deepToString(arr2)); //[[1, 2, 3],[4, 5, 6]]

.equals()는 위 예제에서도 사용했듯이
두 배열에 저장된 모든 요소를 비교해서 같으면 true, 다르면 false를 반환한다.
toString()과 마찬가지로 그냥 .equals()일차원 배열에만 사용 가능하다.
(.equals() 2차원 배열.ver = deepEquals() : 모든 요소에 재귀적 접근을 하기 때문에 차원에 한계 X)

String[][] str2D = {
                {"chair", "의자"},
                {"bed", "침대"}
        };
String[][] str2D2 = {
		{"chair", "의자"},
                {"bed", "침대"}
        };

System.out.println(Arrays.equals(str2D, str2D2)); //false
System.out.println(Arrays.equals(str2D[0], str2D2[0])); // true

System.out.println(Arrays.deepEquals(str2D, str2D2)); // true

복사 - copyOf() | copyOfRange()

두 메서드의 차이는 무엇이냐

  • copyOf([배열 참조 변수], [newLength]) : 배열 전체를 복사해서 새로운 배열을 만들어 반환
    ([newLength] : 필수이며 새롭게 길이를 지정해서 복사해 올 수 있다. _ 왼쪽부터 )

  • copyOfRange([배열 참조 변수], [from] ,[to]) : 배열 일부를 복사해서 새로운 배열을 만들어 반환
    ([to]에 지정된 index의 값은 당연히 포함되지 않는다.)
    또한, 실제 배열 길이보다 긴 range를 지정하면 넘치는 자리는 0으로 채워져서 복사된다.

int[] arr = {0, 1, 2, 3, 4};
int[] arr2 = Arrays.copyOf(arr, arr.length) ; 
int[] arr3 = Arrays.copyOf(arr, 3) ; 
int[] arr4 = Arrays.copyOf(arr, 7) ; // 더 큰 길이 입력
int[] arr5 = Arrays.copyOfRange(arr, 2, 4) ; 
int[] arr6 = Arrays.copyOfRange(arr, 0, 7) ; // 더 큰 길이 입력

System.out.println(Arrays.toString(arr)) ; // [0, 1, 2, 3, 4]
System.out.println(Arrays.toString(arr2)) ; // [0, 1, 2, 3, 4]
System.out.println(Arrays.toString(arr3)) ; // [0, 1, 2]
System.out.println(Arrays.toString(arr4)) ; // [0, 1, 2, 3, 4, 0, 0] _ 0으로 채워짐
System.out.println(Arrays.toString(arr5)) ; // [2, 3]
System.out.println(Arrays.toString(arr6)) ; // [0, 1, 2, 3, 4, 0, 0] _ 0으로 채워짐

정렬 - sort()

말 그대로 정렬할 때 사용하는 메서드이다.

int[] arr = {3, 2, 0, 1, 4};
Arrays.sort(arr);
System.out.println(Arrays.toString(arr)); [0, 1, 2, 3, 4]

0개의 댓글