https://programmers.co.kr/learn/courses/30/lessons/12906
문제
배열 arr가 주어집니다. 배열 arr의 각 원소는 숫자 0부터 9까지로 이루어져 있습니다. 이때, 배열 arr에서 연속적으로 나타나는 숫자는 하나만 남기고 전부 제거하려고 합니다. 단, 제거된 후 남은 수들을 반환할 때는 배열 arr의 원소들의 순서를 유지해야 합니다. 예를 들면,
- arr = [1, 1, 3, 3, 0, 1, 1] 이면 [1, 3, 0, 1] 을 return 합니다.
- arr = [4, 4, 4, 3, 3] 이면 [4, 3] 을 return 합니다.
배열 arr에서 연속적으로 나타나는 숫자는 제거하고 남은 수들을 return 하는 solution 함수를 완성해 주세요.
제한 사항
- 배열 arr의 크기 : 1,000,000 이하의 자연수
- 배열 arr의 원소의 크기 : 0보다 크거나 같고 9보다 작거나 같은 정수
결괏값 예시
arr | answer |
[1,1,3,3,0,1,1] | [1,3,0,1] |
[4,4,4,3,3] | [4,3] |
기본 제공 틀
function solution(arr)
{
var answer = [];
// [실행] 버튼을 누르면 출력 값을 볼 수 있습니다.
console.log('Hello Javascript')
return answer;
}
풀이 [JavaScript]
향상된 for문으로 풀었을 때의 문제점...
제가 이 문제를 처음에 시도했을 때, for( var i in arr ) 향상된 for문 형식으로 풀이를 했습니다.
하지만 이런 형식으로 시도하면, 인덱스의 원래 길이보다 하나 더 많은 길이를 마지막에 꺼내려고 시도하게되는데, 이때 undefined값이 나오게되고, out of range 라는 에러가 뜨지 않습니다. 이는 자바와 다르게 자바스크립트에서 일어나는 현상입니다.
쉽게 말하자면, 배열이 7인 arr에서 위와 같은 방식으로 아래의 로직을 돌리면 arr의 마지막 인덱스인 6에서 + 1의 값을 인덱스로 인식하여 꺼내오려고 하는데 이때, 길이는 7이지만 인덱스의 가장 마지막은 6이기 때문에 인덱스 7의 값은 undefined로 나오게 됩니다.
또한, 다른 문제가 있었는데요.
제가 한가지 간과 했던 점은, 처음엔 arr[i+1]로써 값을 설정했는데, 이렇게 했을 경우에 향상된 for문에서는 var i 에서 이 i가 정규식 for문의 var i = 0과 다르게, string, 즉 문자열로 설정이 된다는 점입니다.
i값이 문자열일 때의 문제점은 arr[i+1]의 값에서 0+1로 연산이 되는 것이 아니라, string i와 1의 문자열 합치기가 되기 때문에, 01, 11, 21 이런식으로 값이 설정되는 오류가 생기게 됩니다.
그러므로, 이런 경우에는 코드를 if(arr[i] !== arr[Number(i)+1]), 이와 같이 i값을 꼭! 숫자로 설정해주는 작업이 필요합니다!
이 또한 이 문제를 풀면서 새로 알게 된 사실이었는데요.
비전공자 개발자들이 쉽게 간과할 수 있는, 놓치기 쉬운 부분이라 꼭 체크해두셨으면 좋겠습니다.
다시 정규식 for문으로...
결국 이러한 현상으로 인해, 다시 정규식 for문을 사용하게 되었습니다.
정규식 for 문을 사용하면 arr의 길이보다 하나 작은 값까지만 돌 수 있게 설정할 수 있고, 길이가 7인 배열은 i가 5까지만 돌 수 있고, 이는 결국 arr상에서 인덱스 5 + 1, 즉 최대 6까지 돌 수 있도록 설정할 수 있었습니다.
제 로직은, 같은 숫자 [1,1,3,3,0,1,1]이 반복될 경우, 앞의 1,1 중 뒤의 1 그리고 3, 3 중 뒤의 3을 answer에 푸쉬하도록 구조를 설정해놓았습니다.
다시 설명하자면, arr[0]과 arr[1] 즉, 1과 1은 같기 때문에 if문의 값은 false가 되어, answer.push구문을 타지 않습니다.
하지만, arr[1]과 arr[2]는 1과 3으로 서로 값이 다르기 때문에 if문의 값을 true가 되어 answer.push 구문을 타게 되고, 그로 인해, 1,1이 반복되었어도 반복된 숫자 중 가장 마지막 값이 answer라는 배열에 추가되게 되는 것입니다.
그리고 마지막에는 answer에 arr의 마지막 값을 푸쉬해주었는데요.
마지막 배열이 연속된 값일 경우
이는 [1,1,3,3,0,1,1]에서 예시를 들자면, 인덱스 6까지의 값을 5와 비교를 했고, 5와 6은 같은 값이기 때문에 answer.push구문을 타지 않아, 1이라는 값이 추가가 되지 않습니다. (로직 상 반복되는 값의 마지막 값을 추가하도록 해놓았기 때문, 같은 값이 앞 뒤로 반복되고 끝나게 된다면, 그 다음의 다른 값이 안나오기 때문에 마지막 값이 추가되는 로직을 타지 못하게된다.)
마지막 배열이 연속되지 않은 값일 경우
이러한 이유와 만약 [1,1,3,3,0,1,2]와 같은 경우에서 1이란 값은 2와 값이 다르기 때문에 answer.push문을 통해 추가가 되지만, 2라는 값은 비교할 대상이 없으므로 추가되는 로직을 탈 수 없게 됩니다.
그렇기 때문에, 마지막 인덱스 값은 무조건 answer에 추가해주어야 하므로, 마지막에 마지막 인덱스 값을 answer에 추가해주는 식으로 구조를 짜보았습니다.
혹시 궁금하거나 이해되지 않는 점이 있다면 댓글 남겨주세요!
function solution(arr){
var answer = [];
for(var i =0; i<arr.length-1; i++ ){
if(arr[i] !== arr[i+1]){
answer.push(arr[i]);
}
}
answer.push(arr[arr.length-1]);
return answer;
}
채점 결과 [JavaScript]
'알고리즘 스터디 > 프로그래머스 스킬체크 레벨 1(끝)' 카테고리의 다른 글
[프로그래머스 스킬체크 레벨 1] 직사각형 별찍기 문제 풀이 및 설명 - 자바스크립트[JAVASCRIPT] (0) | 2021.07.12 |
---|---|
[프로그래머스 스킬체크 레벨 1] 가운데 글자 가져오기 문제 풀이 및 설명 - 자바스크립트[JAVASCRIPT] (0) | 2021.07.12 |
[프로그래머스 스킬체크 레벨 1] 문자열 내 마음대로 정렬하기 문제 풀이 및 설명 - 자바스크립트[JAVASCRIPT] (0) | 2021.05.03 |
[프로그래머스 스킬체크 레벨 1] 제일 작은 수 제거하기 문제 풀이 및 설명 - 자바스크립트[JAVASCRIPT] (0) | 2021.04.29 |
[프로그래머스 스킬체크 레벨 1] 핸드폰 번호 가리기 문제 풀이 및 설명 - 자바스크립트[JAVASCRIPT] (0) | 2021.04.29 |
댓글