문자열을 입력받아 각 문자를 가지고 만들 수 있는 모든 부분집합을 리턴해라
powerSet('abc') = ['', 'a', 'ab', 'abc', 'ac', 'b', 'bc', 'c']
powerSet('jjump') = ['', 'j', 'jm', 'jmp', 'jmpu', 'jmu', 'jp', 'jpu', 'ju', 'm', 'mp', 'mpu', 'mu', 'p', 'pu', 'u']
str문자열을 배열로 바꾸고 Set오브젝트를 사용하여 중복을 제거 해주고, 오름차순(sort)으로 정렬해준다.const dfs = ( arr, ans , depth, result) => {
// 그냥 배열만 같다고 하는 경우에는 주소값을 참조하여 계속해서 값이 바뀌기 때문에 스프레드를 사용하여 그 값만 이용한다.
let res = [...result]
// depth가 배열의 길이보다 길면 리턴을 해준다.
if(depth > arr.length){
return 0
}
// 반복문을 통해 부분 집합들을 전부 ans에 문자열 형식으로 담아준다.
for(let i = depth ; i < arr.length ; i++){
res.push(arr[i])
ans.push(res.join(''))
// 깊이가 마지막일 경우에는 또다시 재귀를 하지 않아도 되니
//마지막 원소가 아닐 경우 다시 재귀를 해주고 depth의 경우에만 i+1로 넘겨준다.
if(i !== arr.length-1) dfs(arr, ans, i+1, res)
// res의 주소값에도 영향이 있으니 result에 값만 다시 초기화 시켜준다.
res = [...result]
}
return ans
}
const powerSet = function (str) {
// 처음에 빈 문자열을 입력해준다.
let ans = ['']
// 중복 및 오름차순 작업
let set = new Set(str.split('').sort())
// 다시 iterable형 배열로 바꾸어준다.
let arr = [...set]
ans = dfs ( arr, ans, 0, [])
return ans
};
res = [...result]로 초기화 시켜주는 이유는 [a,b,c]가 있다고 가정했을 때 만일 [a,b]까지 진행이 되었다고 하자, 그러고 다시 [a,b,c]가 되었고 다시 돌아와서 [a,c]가 되어야 하는데, res = result로 코드를 짰을 경우에는 [a,b,c,c]가 된다. 즉 배열은 주소값을 참조하는 참조형이기 때문에 값을 가르키는 것이 아닌 result의 주소값을 참조하게 되버려 result의 값에 혼동이 오게 된다.