두 개의 문자열을 인수로 받아, 두 문자열에 공통으로 등장하는 모든 부분 문자열을 찾아 새로운 배열로 반환하는 JavaScript 함수를 작성해 보겠습니다.
예를 들어 "IloveLinux"와 "weloveNodejs"라는 두 문자열이 주어졌다면, 두 문자열 모두에 포함된 "love", "ov", "e" 같은 공통 조각들을 찾아 배열 형태로 돌려주는 것이 목표입니다.
구현 코드
const str1 = "IloveLinux";
const str2 = "weloveNodejs";
const findCommon = (str1 = '', str2 = '') => {
const common = Object.create(null);
let i, j, part;
for (i = 0; i < str1.length - 1; i++) {
for (j = i + 1; j <= str1.length; j++) {
part = str1.slice(i, j);
if (str2.indexOf(part) !== -1) {
common[part] = true;
}
}
}
const commonEl = Object.keys(common);
return commonEl;
};
console.log(findCommon(str1, str2));코드 동작 원리
이 함수가 어떻게 작동하는지 단계별로 살펴보겠습니다.
1. 중복 제거를 위한 객체 준비
Object.create(null)을 사용해 프로토타입 체인이 없는 순수한 객체를 생성합니다. 여기서 키(key)는 곧 공통 부분 문자열이 되며, 이미 발견된 문자열이 중복 저장되지 않도록 자동으로 관리해 줍니다.
2. 이중 반복문으로 모든 부분 문자열 추출
바깥쪽 반복문(i)은 시작 인덱스를, 안쪽 반복문(j)은 끝 인덱스를 담당합니다. str1.slice(i, j)를 통해 첫 번째 문자열에서 만들 수 있는 모든 연속된 부분 문자열을 하나씩 뽑아냅니다.
3. 두 번째 문자열과 비교
str2.indexOf(part)를 호출하여 해당 부분 문자열이 두 번째 문자열 안에 존재하는지 확인합니다. 결과가 -1이 아니라면(즉, 존재한다면) common 객체에 기록합니다.
4. 객체를 배열로 변환하여 반환
마지막으로 Object.keys()를 사용해 객체의 키 목록을 배열로 변환한 뒤 반환합니다. 덕분에 중복 없이 공통 부분 문자열만 깔끔하게 정리된 배열을 얻을 수 있습니다.
실행 결과
위 코드를 실행하면 콘솔에 다음과 같은 출력이 나타납니다.
[ 'l', 'lo', 'lov', 'love', 'o', 'ov', 'ove', 'v', 've', 'e' ]
출력 결과를 보면 'l', 'lo', 'lov', 'love'처럼 길이가 점점 늘어나는 부분 문자열부터, 'o', 'v', 'e' 같은 단일 문자까지 두 문자열에 공통으로 포함된 모든 조합이 배열에 담겨 있는 것을 확인할 수 있습니다.
참고 사항
이 방식은 이중 반복문을 사용하기 때문에 시간 복잡도가 O(n²)에 도달할 수 있으며, 내부적으로 indexOf 검색까지 더해지므로 문자열이 매우 길어지면 성능이 저하될 수 있습니다. 다만 짧거나 중간 길이의 문자열을 다룰 때는 직관적이고 충분히 실용적인 접근법입니다. 대소문자를 구분하지 않고 비교하고 싶다면, 함수 진입 시 str1.toLowerCase()와 str2.toLowerCase()로 먼저 정규화해 주면 됩니다.