개발조각

[프로그래머스]튜플 본문

알고리즘🅰/프로그래머스

[프로그래머스]튜플

개발조각 2022. 4. 14. 13:45
728x90
반응형

이번 문제는 split(), map() 메서드의 최종판 문제인 것 같아요.😆

그리고 묘하게 쉬운 문제 같으면서도 생각보다 까다로운? 그런 문제였습니다.

 

 

문제 설명이 길어서 어려운 것처럼 보이지만 쉬운 문제예요.

쉽게 설명하자면

s="{{4,2,3},{3},{2,3,4,1},{2,3}}" 이면

  1. 오름차순으로 정렬하고 : [[3], [2,3], [4,2,3], [2,3,4,1]]
  2. 배열로 다 합친 뒤 : [3, 2,3, 4,2,3, 2,3,4,1]
  3. 중복되는 원소를 제거해 줍니다. : [3, 2, 4, 1]

이런 방식으로 풀면 됩니다.

 

그렇지만 "{{4,2,3},{3},{2,3,4,1},{2,3}}"[[3], [2,3], [4,2,3], [2,3,4,1]]로 바꾸는 게 생각보다 까다로워요.😂

해결방안에 대해서는 아래서 천천히 설명해보겠습니다.


해결방안

function solution(s) {
    let arr1 = s.split('},{').map(a => a.split(',').map(b => b.replace(/{|}/g, '') / 1));
    let arr2 = arr1.sort((a,b)=> a.length - b.length);
    
    var answer = [];
    for(let i=0; i<arr2.length; i++) answer.push(...arr2[i]);
    
    let answer2 = new Set(answer);
    return [...answer2];
}

해결방안 순서

  1. 문자열 s를 2차원 배열로 바꾸기
  2. 각 배열의 길이 순으로 오름차순 하기
  3. 2차원 배열을 1차원 배열로 합치기
  4. 중복되는 원소 제거하기

 

 

 

1단계. 문자열 s를 2차원 배열로 바꾸기

let arr1 = s.split('},{').map(a => a.split(',').map(b => b.replace(/{|}/g, '') / 1));

"{{20,111},{111}}" -> [[20, 111], [111]]

1단계에서는 위와 같은 결과를 만들어주는 코드입니다.

 

 

split('},{')

문자열을 제어하는 것보다 배열로 만들어서 제어를 하는 게 좋을 것 같다는 생각이 들었습니다.

문자열을 배열로 만들기 위해 가장 쉬운 방법은 split()메서드를 이용하는 방법이라 split()메서드를 사용했는데요.

split()메서드를 사용했을 때 문자열 s를 최대한 구분하기 위해 ('},{')을 넣어주었습니다.

테스트 3 s="{{20,111},{111}}"

split('},{') -> [ '{{20,111', '111}}' ]

 

 

map(a => a.split(',').map(b => b.replace(/{|}/g, '')

앞에서 1차원 배열을 만들었고 이번에는 2차원 배열을 만들기 위해 map() 메서드 안에 split()메서드, map()메서드를 넣어서 코드를 작성했습니다.

  • split() 메서드는 String 객체를 지정한 구분자를 이용하여 여러 개의 문자열로 나눕니다.
  • map() 메서드는 배열 내의 모든 요소 각각에 대하여 주어진 함수를 호출한 결과를 모아 새로운 배열을 반환합니다.

 

1. s.split('},{').map(a=>a.split(','))

map()메서드를 안에 split()메서드를 사용하여 1차원 배열을 2차원 배열로 만들었습니다.

split()메서드를 사용할때 ,(콤마) 기준으로 나누었습니다.

s.split('},{').map(a=>a.split(',')) 테스트

테스트 3
s.split('},{') = [ '{{20,111', '111}}' ]
map(a=>a.split(',')) 여기서 a'{{20,111', '111}}'를 나타냅니다.

map(a=>a.split(',')) -> [ [ '{{20', '111' ], [ '111}}' ] ]

 

2. s.split('},{').map(a => a.split(',').map(b => b.replace(/{|}/g, '')));

2차원 배열 안의 원소의 값을 숫자만 남기기 위해 {,}는 제거해주었습니다.

{,}를 제거하기 위해 replace()메서드와 정규식을 써서 제거해 주었습니다.

  • replace() 메서드는 어떤 패턴에 일치하는 일부 또는 모든 부분이 교체된 새로운 문자열을 반환합니다.
  • 앞쪽 : /{|}/g -> {와 }를 일치하는 부분을 찾아주세요.
  • 뒤쪽 : '' -> 앞쪽에서 일치되는 부분을 빈 값으로 교체해주세요.

 

정규식이 잘 썼는지 확인할 때 쓰면 좋을 것 같아서 올려봅니다~😊

https://regexr.com/

 

RegExr: Learn, Build, & Test RegEx

RegExr is an online tool to learn, build, & test Regular Expressions (RegEx / RegExp).

regexr.com

s.split('},{').map(a => a.split(',').map(b => b.replace(/{|}/g, ''))); 테스트

테스트 3
s.split('},{') = [ '{{20,111', '111}}' ]
map(a=>a.split(',')) -> [ [ '{{20', '111' ], [ '111}}' ] ]
map(b => b.replace(/{|}/g, '')); 여기서 b'{{20', '111', '111}}'를 나타냅니다.

map(b => b.replace(/{|}/g, ''))); -> [ [ '20', '111' ], [ '111' ] ]

 

3. s.split('},{').map(a => a.split(',').map(b => b.replace(/{|}/g, '') / 1));

마지막으로 1단계-2를 보시면

2차원 배열의 원소가 숫자가 아니라 ''로 묶여 있는 문자열입니다.

중복 map()을 사용해서 2차원 배열의 원소를 바꿔줄 때 문자열을 숫자로 바꾸어주면 좋겠다고 생각이 들었습니다.

그래서 저는 "문자열과 숫자열의 사칙연산"을 사용해주었습니다.

 

문자열과 숫자열의 사칙연산은 숫자가 나오기 때문에 /1을 해주었습니다.

s.split('},{').map(a => a.split(',').map(b => b.replace(/{|}/g, '') / 1)); 테스트

테스트 3
s.split('},{') = [ '{{20,111', '111}}' ]
map(a=>a.split(',')) -> [ [ '{{20', '111' ], [ '111}}' ] ]
map(b => b.replace(/{|}/g, ''))); -> [ [ '20', '111' ], [ '111' ] ]

map(b => b.replace(/{|}/g, ''))/1); -> [ [ 111 ], [ 20, 111 ] ]

 

 

 

2단계. 각 배열의 길이 순으로 오름차순 하기

let arr2 = arr1.sort((a,b)=> a.length - b.length);

오름차순으로 정렬하면 문제를 풀 때 쉽게 해결돼서 sort()메서드로 정렬을 해주었습니다.

오름차순으로 정렬할 때 배열의 길이 순으로 해주었습니다.

그래서 a-b가 아닌 a.length - b.length로 해주었습니다.

 

테스트 3 s= "{{20,111},{111}}"
arr1 = [ [ 111 ], [ 20, 111 ] ]

arr1.sort((a,b)=> a.length - b.length); -> [ [ 111 ], [ 20, 111 ] ]

 

3단계. 2차원 배열을 1차원 배열로 합치기

var answer = [];
for(let i=0; i<arr2.length; i++) answer.push(...arr2[i]);

4단계에서 중복되는 원소를 제거할 거라서 만들어둔 2차원 배열을 1차원 배열로 합쳐주었습니다.

간단하게 for문을 사용해서 합쳐주었습니다.

테스트 3 s= "{{20,111},{111}}"
arr2 = [ [ 111 ], [ 20, 111 ] ]

var answer = [];
for(let i=0; i<arr2.length; i++) answer.push(...arr2[i]);

answer= [ 111, 20, 111 ]

 

 

4단계. 중복되는 원소 제거하기

let answer2 = new Set(answer);
return [...answer2];

마지막으로 중복되는 원소를 제거해주었는데요.

중복되는 자료를 없애는 방법은 많지만 이번에는 Set자료형을 사용해주었습니다.

Set자료형은 Array의 데이터 중복 제거할 때 많이 씁니다.

알고 있으면 좋을 것 같아서 한번 사용해보았습니다.

테스트 3 s= "{{20,111},{111}}"
answer= [ 111, 20, 111 ]

let answer2 = new Set(answer); -> Set { 111, 20 }
return [...answer2]; -> [111, 20]

프로그래머스 튜플 해결방안 설명은 여기까지입니다.

728x90
반응형
Comments