본문 바로가기

Java/코딩테스트

[프로그래머스/181903] qr code (배열과 String 클래스의 문자 접근 방식이 다른 이유, .charAt())

✏️ 문제 설명

두 정수 q, r과 문자열 code가 주어질 때, code의 각 인덱스를 q로 나누었을 때 나머지가 r인 위치의 문자를 앞에서부터 순서대로 이어 붙인 문자열을 return 하는 solution 함수를 작성해 주세요.

 


✏️ code

🖥️ Java에서 배열과 String 클래스의 문자 접근 방식이 다른 이유

👉🏻 메모리 관리와 객체 특성 차이에서 비롯됩니다.
  • 배열의 메모리 접근 방식
    • 배열: 메모리에 연속적으로 저장, 원소는 해당 데이터 타입의 크기만큼 메모리 공간을 차지합니다.
      =>  따라서 인덱스를 통해 직접적으로 메모리에 접근할 수 있습니다.
      • int[] numbers = {1,2,3,4,5};
        => numbers[2]는 세 번째 메모리 주소를 직접 참조합니다.
  • String 클래스의 메모리 접근 방식
    • String 클래스: 불변 객체입니다. 즉, 한번 생성된 String 객체의 내용이 변경될 수 없음을 의미합니다.
      • String 객체는 내부적으로 문자 배열을 사용하지만, 이를 직접 노출하지 않고 메서드를 통해 접근하도록 설계되어 있습니다.
  • 접근 방식 차이의 이유
    • 불변성 유지: String의 불변성을 보장하기 위해 직접적인 메모리 접근 허용하지 않습니다.
      chatAt() 메서드를 사용해 내부 데이터 변경을 방지합니다.
    • 메모리 최적화: Java는 String 객체를 String Constant Pool에서 관리하는데, 이를 통해 동일한 문자열에 대해 메모리 주소를 공유하여 Heap 영역의 메모리를 절약합니다.

왼쪽 이미지: str = "abc" 후에 str = "def"가 실행되어 str이라는 변수가 갖는 참조 값이 0x11에서 0x22로 바뀐다 하더라도 그건 str 변수가 갖는 참조값이 변경된 것이지, 실제 "abc"가 저장되어 있는 0x11 주소의 데이터가 바뀌는 것이 아닙니다.오른쪽 이미: String 리터럴로 생성하면 해당 String은 Heap 영역 내 String Constant Pool에 저장되어 재사용됩니다. 반면 new 연산자로 생성하면 같은 내용이라도 여러 개의 객체가 각 Heap 영역을 차지하게 됩니다.

 

📌code.chatAt(i)

  • i % q == r: i/q의 나머지 값이 r과 동일하다면
  • result.append(code.charAt(i)): code의 i번째 문자를 result에 추가합니다.
class Solution {
    public String solution(int q, int r, String code) {
        StringBuilder result = new StringBuilder();
        for (int i = 0; i < code.length(); i++) {
            if (i%q == r) {
                result.append(code.charAt(i));
            }
        }
        return result.toString();
    }
}

 


반응형