JavaScript/알고리즘

프로그래머스 수 조작하기 2 JS ( for문 / 객체활용하기 )

hihiha2 2023. 7. 11. 22:19

문제 설명

정수 배열 numLog가 주어집니다. 처음에 numLog[0]에서 부터 시작해 "w", "a", "s", "d"로 이루어진 문자열을 입력으로 받아 순서대로 다음과 같은 조작을 했다고 합시다.

  • "w" : 수에 1을 더한다.
  • "s" : 수에 1을 뺀다.
  • "d" : 수에 10을 더한다.
  • "a" : 수에 10을 뺀다.

그리고 매번 조작을 할 때마다 결괏값을 기록한 정수 배열이 numLog입니다. 즉, numLog[i]는 numLog[0]로부터 총 i번의 조작을 가한 결과가 저장되어 있습니다.

주어진 정수 배열 numLog에 대해 조작을 위해 입력받은 문자열을 return 하는 solution 함수를 완성해 주세요.

 

🙋‍♀️ 내 생각

numLog의 배열을 돌면서 하나뒤의 인덱스와 앞의 인덱스의 차를 통해서 "w","s","d","a"문자열을 더해나가는 문제이다.

 

나는 배열을 돌면서 특정한 작업을 하기 위해서 for문을 이용하였고 복합할당연산자 +=를 통해서 해당되는 값의 문자열을 result라는 빈배열에 더하는 방식으로 풀었다.

 

 

 

✅ 내 코드

function solution(numLog) {
    let result =""
    for(i=0; i<numLog.length; i++){
        if(numLog[i+1]-numLog[i]===1){
            result += "w"
        } else if (numLog[i+1]-numLog[i]===-1){
            result += "s"
        } else if (numLog[i+1]-numLog[i]===10){
            result += "d"
        } else if(numLog[i+1]-numLog[i]===-10) {
            result += "a"
        }
    } return result
}

우선, 문자열을 더해줄 빈문자열을 result라는 변수에 담는다.

 

그런다음 for문을 통해서 numLog배열을 돌면서 특정작업을 수행한다.

인덱스가 0부터 시작되고, numLog의 길이만큼 반복되므로 i=0; numLog.length;로 범위를 지정한다.

 

if를 통해서 각각에 해당하는 조건을 정해서 특정 작업을 수행하도록 나누었다.

numLog[i+1]-numLog[i]를 통해서 바로 뒤의 인덱스의 요소와 그 앞의 인덱스의 요소의 차를 구하도록 했다.

(풀고 보니 저렇게 반복되기 때문에 변수에 담아서 if문에 넣어주었으면 더 가독성이 좋은 코드가 되었을 것 같다)

 

경우는 4가지이기때문에 4가지로 나누었다.

차가 1이면 result에 "w"를 더하고, 차가 -1이면 "s", 10이면 "d", -10이면 "a"를 더한다.

 

마지막으로 result를 리턴한다.

 

 

✔️ 개선할 점

1. 범위지정

현재요소- 다음요소를 통해서 연산을 하고 있기때문에 i=numLog.length-1까지 반복한다면,  마지막요소-없는값이 될 수가 있다.

그래서 이렇게 범위가 넘어가는 경우가 생기지 않도록 범위를 i<numLog.length-1로 바꿔서 i=numLog.length-2까지만 진행되도록 한다.

 

2. 가독성

numLog[i+1]-numLog[i] 의 값이 if문의 조건식안에서 계속 반복되고 있기때문에, 이 값은 따로 변수로 선언하여 가독성을 높인다.

 

 

✔️ 개선한 코드

function solution(numLog) {
    let result =""
    for(i=0; i<numLog.length-1; i++){
        const subtraction = numLog[i+1]-numLog[i];
        if(subtraction===1){
            result += "w"
        } else if (subtraction===-1){
            result += "s"
        } else if (subtraction===10){
            result += "d"
        } else if(subtraction===-10) {
            result += "a"
        }
    } return result
}

 

 

 

💻  다른사람 코드중에 배울 것 

function solution(numLog) {
    const convert = {
        '1': 'w', '-1': 's', '10': 'd', '-10': 'a'
    };

    return numLog.slice(1).map((v, i) => {
        return convert[v - numLog[i]]
    }).join('')
}

convert라는 객체를 선언하여, 객체에 각각의 숫자에 대응하는 문자를 저장한다.

 

그런 다음 slice(1)을 통해, numLog의 맨 앞의 값을 제거한다.

테스트코드를 통해 보면 slice(1)을 해주면 [1, 0, 10, 0, 1, 0, 10, 0, -1, -2, -1]이 남는다.

 

맨 앞이 제거된 배열을 map을 사용하여 배열의 각 요소에 변환작업을 수행한다.

v는 현재요소의 값, i는 현재요소의 인덱스이다. 

v - numLog[i]는 현재 요소 v에서 해당 요소의 인덱스 i번째 원소 numLog[i]를 뺀 값이다.

v - numLog[i]를 통해서 현재요소-다음요소의 차를 구할 수 있다. 예를 들면, 첫번째반복의 v는 1, numLog[0]=0이다.

값이 나온것은 객체 convert의 key값이다. 그러므로 1-0 = 1이 되어 "w"를 리턴한다. ( conver['1']:'w'이므로 )

두번째반복의 v는 0, numLog[1]=1이다. 0-1 = -1이므로 "s"를 리턴한다.

 

반복문을 돌면서 끝까지 작업을 다 수행하면, join('')을 통해서 하나의 문자열로 만든다.

 

이렇게 객체로 만들어서 풀면 코드의 가독성이 올라갈 뿐만 아니라, 경우의 수가 늘어난다고 하더라도 코드가 매우 간결해질수있다.

다음에 또 이런 문제를 푼다면 위와 같이 객체를 만들어서 문제를 해결해야겠다는 생각이 들었다.

 

 

💻 객체의 Key값에 접근하는 법

자바스크립트에서 자주 사용되는 객체의 key에 접근하는 방법은 dot notation과 bracket notation이다.

 

1️⃣ 점 표기법 (Dot notation): 객체의 키가 유효한 식별자(identifier)인 경우에 사용

const obj = {
  key: "value"
};

console.log(obj.key); // "value"

 

2️⃣ 대괄호 표기법 (Bracket notation): 객체의 키가 유효한 식별자가 아니거나 동적으로 키에 접근해야 할 때 사용

대괄호 안에 키를 문자열로 작성

const obj = {
  "key with space": "value"
};

console.log(obj["key with space"]); // "value"

 

위의 코드에서는 대괄호표기법을 통해서 객체의 키값에 접근하고 있다.

 

 

 

🙋‍♀️ 내 생각

확실히 객체를 사용하여 문제를 푼 코드가 가독성도 높고 코드도 간결하다. 실제 실무를 할때는 위와 같은 경우보다 경우의 수가 매우 커지는 경우가 생길 것이라고 생각한다. 알고리즘을 통해서 평소에 이러한 문제를 객체를 통해서 더 효율적으로 처리할 수 있는 방법을 익숙해지도록 연습하면 좋을 것같다. 다음번에는 꼭 객체를 활용하여 문제를 풀어야겠다.