본문 바로가기
코딩테스트

[프로그래머스 Lv.1 / Java] 음양 더하기

by 지지 2022. 2. 5.

[문제]

음양 더하기

어떤 정수들이 있습니다. 이 정수들의 절댓값을 차례대로 담은 정수 배열 absolutes와 이 정수들의 부호를 차례대로 담은 불리언 배열 signs가 매개변수로 주어집니다. 실제 정수들의 합을 구하여 return 하도록 solution 함수를 완성해주세요.

제한사항

● absolutes의 길이는 1 이상 1,000 이하입니다.

→absolutes의 모든 수는 각각 1 이상 1,000 이하입니다.

● signs의 길이는 absolutes의 길이와 같습니다.

→signs[i] 가 참이면 absolutes[i] 의 실제 정수가 양수임을, 그렇지 않으면 음수임을 의미합니다.

입출력 예

absolutes
signs
result
[4,7,12]
[true,false,true]
9
[1,2,3]
[false,false,true]
0

입출력 예 설명

입출력 예 #1

signs가 [true,false,true] 이므로, 실제 수들의 값은 각각 4, -7, 12입니다.

따라서 세 수의 합인 9를 return 해야 합니다.

입출력 예 #2

signs가 [false,false,true] 이므로, 실제 수들의 값은 각각 -1, -2, 3입니다.

따라서 세 수의 합인 0을 return 해야 합니다.


[풀이]

● 첫 번째 풀이(2중 for문 노가다 코드) - 같은 실수를 반복해서 스스로에게 짜증났던 코드...

class Solution {
    public int solution(int[] absolutes, boolean[] signs) {
        int answer = 0;

        for(int i = 0; i<absolutes.length; i++){
            for (int j = i; j<signs.length;){
                if(signs[j]==false){
                    absolutes[i] = -1 * absolutes[i];
                    answer += absolutes[i];
                    break;
                } else {
                    answer += absolutes[i];
                    break;
                }
            }
        }
        return answer;
    }
}

1. 배열 absolutes, signs의 길이만큼 이중 for문을 돌려준다.(벌써부터 비효율적)

2. signs배열의 요소가 false라면, 같은 인덱스 번호를 가진 absolutes요소에 -1을 곱해주어 음수로 만들어 answer에 더해주고, 반대로 true라면 양수 absolutes[i]의 값을 가져가서 answer에 더해준다.

3. 계산이 끝나면 break문으로 안쪽 for문을 빠져나와주고, 다시 absolutes배열의 다음 요소부터 출발한다.

- 안쪽 for문의 j 시작 값을 i로 준 이유가 여기서 나온다. absolutes배열의 인덱스 번호와 같은 인덱스 번호를 가진 signs배열의 요소값을 비교해주어야하기 때문이다.

4. 그렇게 주어진 배열의 크기만큼 absolutes를 음수 또는 양수로 만들어 주어 모든 값을 answer에 더해주면 최종 답이 나오게된다.

 

● 두 번째 풀이(그나마 나은 for문 코드)

class Solution {
    public int solution(int[] absolutes, boolean[] signs) {
        int answer = 0;
        
        for(int i = 0; i<absolutes.length; i++){
            if(signs[i]==false){
                absolutes[i] = -1 * absolutes[i];
                answer += absolutes[i];
            } else {
                answer += absolutes[i];
            }
        }
        return answer;
    }
}

1. 생각해보니..... 어차피 같은 인덱스 번호끼리를 비교해주어야 한다면 for문을 굳이 두 번 돌릴 필요가 없었다.

- 각 배열의 같은 인덱스 번호를 가진 i값끼리만 비교할거니까!

2. 마찬가지로 signs[i]의 값이 false라면 absolutes[i]값을 음수로, true라면 양수를 answer 변수에 계속 더해준다.

3. 배열 길이만큼의 for문이 돌면 answer엔 모든 값이 더해진 최종 답이 들어가게 된다.

 

● 세 번째 풀이(삼항연산자를 이용한 코드)

class Solution {
    public int solution(int[] absolutes, boolean[] signs) {
        int answer = 0;
        
        for(int i = 0; i<absolutes.length; i++){
            answer += (signs[i]? absolutes[i] : -1 * absolutes[i]);
        }
        return answer;
    }
}

 

1. for문은 똑같이 돌려준다.

2. 여기서 if문을 일반 if문이 아닌 삼항연산자를 사용해준다.

- signs[i]가 true면? absolutes[i](양수)를, 그게 아니라면(false라면) -1 * absolutes[i]의 음수값을 answer에 계속 더해주면 된다.

3. 마찬가지로 배열 길이만큼의 for문이 돌면 answer엔 모든 값이 더해진 최종 답이 들어가게 된다.

- if문으로 조건을 많이 넣어주는게 아니라면 삼항연산자를 이용하자.

 

● 다른 사람의 풀이

class Solution {
    public int solution(int[] absolutes, boolean[] signs) {
        int answer = 0;

        for (int i=0; i<signs.length; i++)
            answer += absolutes[i] * (signs[i]? 1: -1);
        return answer;
    }
}

- 이 분은 나의 세번 째 도전과 거의 흡사하지만, 삼항연산자를 다루는 부분에서 앗 이런방법이!! 싶어서 가져와봤다. signs[i]가 false인지 true인지 먼저 비교하고 일일이 음수, 양수를 결정지었던 나와 달리 absolutes[i] * 를 먼저 써준 후 signs[i]가 true라면 1을 곱하고, 그것이 아니라면 -1을 곱해주는 것으로 코드를 작성하셨다. 굿!


[느낀점]

코딩테스트 연습을 마지고 100점을 받으면 다른 사람의 코드를 볼 수 있다. 볼 때 마다 헉.... 소리가 절로 나오는 코드들이 많다. 코딩테스트를 통과했다고 하더라도 내 코드는 100점이 아닌 것 같다...

며칠 전 '내적' 문제에서도 같은 실수를 반복했는데... 그래도 그 때의 경험을 발판 삼아 계속 코드를 고쳐나가며 실수를 알아냈다는 점에서는 칭찬해주고 싶다.

항상 통과를 해도 코드를 몇번이고 더 보면서 더 효율적인 코드로 바꾸는 연습을 하는데도 부족한 것이 느껴진다.

틀에 갇혀있지 말고 다양한 방법으로 접근해보는 연습을 많이 해야겠다. 중복을 많이 줄여보자!!!

댓글