이번 글에서는 두 개의 문자열을 인수로 받아, 첫 번째 문자열 중 두 번째 문자열에도 포함된 문자만 남기고 나머지는 모두 제거한 새로운 문자열을 반환하는 JavaScript 함수를 작성해 보겠습니다.
중요한 점은 결과 문자열에서 문자들이 등장하는 순서가 바뀌어서는 안 된다는 것입니다. 즉, 결과물은 반드시 첫 번째 문자열과 동일한 순서를 그대로 유지해야 합니다.
예제 코드
이 문제를 해결하는 코드는 다음과 같습니다.
const str1 = 'abcdefgh';
const str2 = 'banana';
const deleteSelectively = (str1 = '', str2 = '') => {
let strArr1 = str1.split('');
const strArr2 = str2.split('');
const map = {};
strArr2.forEach(el => {
map[el] = 1;
});
strArr1 = strArr1.filter(el => {
return map.hasOwnProperty(el);
});
return strArr1.join('');
};
console.log(deleteSelectively(str1, str2));실행 결과
콘솔에 출력되는 결과는 다음과 같습니다.
ab
코드 동작 원리
위 코드가 어떻게 동작하는지 단계별로 살펴보겠습니다.
- 문자열 분리: split('') 메서드를 사용해 두 문자열을 각각 개별 문자의 배열로 변환합니다.
- 조회용 맵 생성: 두 번째 문자열의 각 문자를 객체(map)의 키로 저장합니다. 이렇게 하면 특정 문자의 존재 여부를 상수 시간(O(1))에 확인할 수 있습니다.
- 필터링: filter() 메서드와 hasOwnProperty()를 조합해, 첫 번째 문자열의 문자 중 map에 등록된(즉, 두 번째 문자열에도 존재하는) 문자만 남깁니다.
- 다시 결합: join('') 메서드로 필터링된 문자 배열을 하나의 문자열로 합쳐 반환합니다.
'abcdefgh'와 'banana'의 경우, 두 문자열에 공통으로 존재하는 문자는 'a'와 'b'뿐입니다. 따라서 첫 번째 문자열에서의 순서대로 'ab'가 출력됩니다.
이 알고리즘의 시간 복잡도는 두 문자열의 길이를 각각 n, m이라 할 때 O(n + m)으로 매우 효율적이므로, 긴 문자열을 다룰 때에도 안정적인 성능을 기대할 수 있습니다.