이쿠의 슬기로운 개발생활

함께 성장하기 위한 보안 개발자 EverNote 내용 공유

코딩테스트

[프로그래머스][JAVA] 키패드 누루기

이쿠우우 2022. 10. 3. 11:44
반응형

 

 

질문

친구가 해당 문제를 JAVA로 풀이하는 과정 중에
풀긴했는데, == 랑 equals랑 했을 때 값이 다르게 나오는데 왜 다르게 나오는지에 대해 질문함.

 

친구가 문제를 풀이 할 때
String 문자열 비교 시 "=="을 사용하면 반은 맞고 반은 틀리는데
"equals" function을 사용하면 모두 맞는다고 함.
그래서 일단 String 비교는 equals로 비교해야한다 라고만 외워놓았다고 함.
 

답변

 

문제 상황

JAVA에서 String 변수에 값을 대입하는 방법은 다음과 같이 두가지가 있음.
 
String str1 = new String("Hello!");
String str2 = "Hello!";
 
str1, str2 모두 결과적으로만 보면 변수에 "Hello!" 라는 데이터가 들어감.
 
이 상황에서 str1 == str2 결과를 확인해보면
false가 출력됨.
저장되어있는 문자열이 같으니 true를 예상했지만
실제 결과는 false가 출력되어 개발 시 디버깅에 어려움을 겪을 수 있음.

 

원인

[String str2 = "Hello!"; 설명]
String str2 = "Hello!";
와 같이 선언하는 걸 Literal 선언이라고 함.
Literal 선언의 경우 JAVA 메모리 구조 중에 Pool 영역에 저장이 됨.
String이면 String Pool 영역에 저장이됨.
 
여기서 Pool이란 java의 특징인데
JAVA에서는 Stack, Heap 영역과는 별개로
메모리와 속도를 향상 시키기 위해 상수Pool이라는 영역을 사용함.
상수Pool은 Heap영역에 위치하고 있고 JAVA 프로세스가 종료될 때 까지 유지됨.
더 자세하게 설명하자면
String을 Literal 형식으로 data를 저장할 경우
내부적으로 new String() 메소드 호출 이후에 String.intern()이라는 메소드가 호출되어
고유의 인스턴스를 공유하도록 interned 됨.
이것은 생성한 String을 Constant pool에 등록하는 작업을 수행함.
(만약 이전에 같은 char sequence의 문자열이 이미 상수풀에 있다면 
문자열을 힙에서 해제하고 그 상수풀의 레퍼런스를 반환)
 
[String str1 = new String("Hello!"); 설명]
String new 방식으로 선언하면 객체를 생성하게되어 Heap영역에 data가 저장됨.
매번 Heap 영역에 data가 저장이 되니 아래와 같이 3개의 변수를 선언하는데 모두 같은 값으로 선언하는 경우
String str1 = new String("Hello!");
String str2 = new String("Hello!");
String str3 = new String("Hello!");
모두 각각의 위치를 가지게됨.
 
[ "==" 연산자 설명]
String은 문자열을 주소를 가리키고 있음.
c/c++의 포인터와 같은 개념임.
srt1 == str2의 경우 각 String이 가리키고 있는 주소값을 비교하게됨.
그래서 다음과 같은 결과가 나옴.
String str1 = "Hello!";
String str2 = "Hello!";
의 결과는 true가 나옴.
왜냐하면 Literal 방식으로 선언하는 경우
Heap의 String Pool 영역에 "Hello!" 문자열을 저장하는 영역이 존재하고
str1, str2 모두 같은 문자열을 저장할려고 하니 두개 변수 모두 "Hello!" 영역의 주소를 가리키게 됨.
그래서 "==" 방식으로 비교하는 경우 같은 주소를 비교하게되니 true를 리턴함.
 
String str1 = new String("Hello!");
String str2 = "Hello!";
의 결과는 false가 나옴.
str2는 String Pool 영역에 있는 "Hello!" 문자열의 주소를 가리키게 되고
str1은 객체를 새로 생성하니 Heap영역에 있는 "Hello!" 문자열 주소를 가리키게 됨.
즉 서로 가리키는 문자열의 주소가 다르니 false를 리턴함.

 

결과

java 에서 String 문자열 비교를 하기 위해서는
String 객체의 equals 함수를 사용해야함.
equals 함수는 주소가 아닌
String 이 가리키는 주소에 있는 data를 비교하는 함수임.

 

내가 풀이한 JAVA 답변

class Solution {
    
    int[] location(int num){
        
        int[] result = new int[2];
        
        if(1 == num){
            result[0] = 0;
            result[1] = 0;
        }
        else if(2 == num){
            result[0] = 0;
            result[1] = 1;
        }
        else if(3 == num){
            result[0] = 0;
            result[1] = 2;
        }
        else if(4 == num){
            result[0] = 1;
            result[1] = 0;
        }
        else if(5 == num){
            result[0] = 1;
            result[1] = 1;
        }
        else if(6 == num){
            result[0] = 1;
            result[1] = 2;
        }
        else if(7 == num){
            result[0] = 2;
            result[1] = 0;
        }
        else if(8 == num){
            result[0] = 2;
            result[1] = 1;
        }
        else if(9 == num){
            result[0] = 2;
            result[1] = 2;
        }
        else if(0 == num){
            result[0] = 3;
            result[1] = 1;
        }


        return result;
    }
    
    private String middle(int num, int[] left, int[] right, String hand){
        String result = "";
        int[] targetLocation = location(num);        


        int resultL = 0;
        int resultR = 0;


        int tempL = left[0] - targetLocation[0];
        if (tempL < 0){
            tempL *= -1;
        }
        resultL = tempL;
        tempL = left[1] - targetLocation[1];
        if (tempL < 0){
            tempL *= -1;
        }
        resultL += tempL;


        int tempR = right[0] - targetLocation[0];
        if (tempR < 0){
            tempR *= -1;
        }
        resultR = tempR;
        tempR = right[1] - targetLocation[1];
        if (tempR < 0){
            tempR *= -1;
        }
        resultR += tempR;


        if(resultR == resultL){  
            if (hand.equals("right")){ // 해당 부분을 if ("right" == hand) 로 "==" 형식으로 하면 오답임.
                result = "R";
            }
            else{
                result = "L";
            }
        }
        else if(resultR > resultL){
            result = "L";
        }
        else if(resultR < resultL){
            result = "R";
        }


        return result;
    }
    
    public String solution(int[] numbers, String hand) {
        String answer = "";
        
        int[] left = {3,0};
        int[] right = {3,2};
        
        for(int i=0; i< numbers.length; i++){
            int target = numbers[i];
            if((1 == target) || (4 == target) || (7 == target)){
                answer += "L";
                left = location(target);
            }
            else if((3 == target) || (6 == target) || (9 == target)){
                answer += "R";
                right = location(target);
            }
            else{
                String middleResult = middle(target, left, right, hand);
                answer += middleResult;
                if ("L" == middleResult){
                    left = location(target);
                }
                else{
                    right = location(target);
                }
            }                             
        }
        
        return answer;
    }
}
반응형