Computer >> 컴퓨터 >  >> 프로그래밍 >> JavaScript

자바스크립트로 배열 속 유일하게 다른 문자열 찾기

문제 개요

문자열 배열을 입력받는 자바스크립트 함수를 작성해야 합니다. 배열에 담긴 대부분의 문자열은 동일한 문자들(또는 그 문자들의 반복)로 이루어져 있으며, 단 하나의 문자열만 서로 다른 문자 집합으로 구성되어 있습니다. 우리가 만들 함수는 바로 그 유일한 문자열을 찾아 반환해야 합니다.

예시

배열이 다음과 같다고 가정해 보겠습니다.

['ba', 'abc', 'acb', 'bac', 'foo', 'bca', 'cab', 'cba']

위 배열에서 나머지 문자열들은 모두 a, b, c 세 글자로 이루어져 있지만, 'foo'만 f와 o라는 전혀 다른 문자로 구성되어 있습니다. 따라서 함수가 반환해야 하는 값은 'foo'입니다.

주의할 조건

문자열에는 공백이 포함될 수 있지만, 공백은 판단 기준에서 제외됩니다. 즉, 공백이 아닌 문자들만 비교 대상이 되며, 공백으로만 이루어진 문자열은 빈 문자열과 마찬가지로 취급합니다. 또한 배열에는 항상 3개 이상의 문자열이 존재한다고 보장됩니다.

해결 접근 방식

핵심 아이디어는 간단합니다. 모든 문자열의 문자를 정렬해서 표준 형태로 통일하면, 같은 문자로 구성된 문자열들은 완전히 동일한 형태가 됩니다. 그중 단 하나만 다른 형태를 띠게 되므로, 정렬된 결과를 비교하면 유일한 문자열을 쉽게 걸러낼 수 있습니다.

구체적인 처리 순서는 다음과 같습니다.

1. 각 문자열을 소문자로 변환하고 공백을 모두 제거한 뒤, 문자 단위로 분리합니다.
2. 분리된 문자 배열을 정렬하여 문자 구성을 정규화합니다.
3. 정렬된 문자들을 다시 하나의 문자열로 합칩니다.
4. 정렬된 목록의 첫 번째 요소와 마지막 요소를 비교해 어느 쪽이 유일한 값인지 판별합니다.
5. 해당 값의 인덱스를 이용해 원본 배열에서 실제 문자열을 찾아 반환합니다.

구현 코드

const arr = ['ba', 'abc', 'acb', 'bac', 'foo', 'bca', 'cab', 'cba'];

const findOnlyUnique = (arr = []) => {
   // 1단계: 소문자 변환, 공백 제거 후 문자 배열로 분리하고 정렬
   const first = [];
   for (i = 0; i < arr.length; i++) {
      first.push(arr[i].toLowerCase().replace(/\s/g, '').split(''));
      for (j = 0; j < arr[i].length; j++) {
         first[i].sort();
      }
   }

   // 2단계: 정렬된 문자 배열을 다시 문자열로 결합
   const second = [];
   for (k = 0; k < arr.length; k++) {
      second.push(first[k].join());
   }
   second.sort();

   // 3단계: 첫 번째와 마지막 값을 비교해 유일한 문자열 판별
   const third = [];
   if (second[1] !== second[second.length - 1]) {
      third.push(second[second.length - 1]);
   } else {
      third.push(second[0]);
   }

   // 4단계: 원본 배열에서 해당 문자열 찾기
   const last = [];
   for (let n = 0; n < first.length; n++) {
      last.push(first[n].join(','));
   }
   return arr[last.indexOf(third[0])];
};

console.log(findOnlyUnique(arr));

실행 결과

foo

코드 동작 원리 살펴보기

배열의 각 문자열에 대해 toLowerCase()로 대소문자 차이를 없애고, replace(/\s/g, '')로 공백을 제거한 후 split('')으로 한 글자씩 분리합니다. 이어서 sort()를 호출하면 'abc', 'acb', 'bac'처럼 순서만 다른 문자열들이 모두 'abc'라는 동일한 형태로 정규화됩니다.

정규화된 목록을 다시 정렬하면 동일한 구성의 문자열들이 앞쪽에 몰리고, 유일하게 다른 문자열('foo')은 맨 끝에 위치하게 됩니다. 따라서 두 번째 요소와 마지막 요소를 비교했을 때 값이 다르다면 마지막 요소가 유일한 문자열이고, 같다면 첫 번째 요소가 유일한 문자열입니다.

마지막으로 정규화된 형태를 기준으로 원본 배열에서의 위치(indexOf)를 찾아 실제 문자열을 반환하면, 우리가 원하는 답인 'foo'를 얻을 수 있습니다.