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

JavaScript에서 문자열 내 하위 문자열을 단락(

) 태그로 감싸는 방법

문제 소개

JavaScript 함수를 하나 작성해야 합니다. 이 함수는 첫 번째 인수로 문자열 str을, 두 번째 인수로 문자열 배열 arr을 전달받으며, str 안에서 arr에 포함된 하위 문자열을 찾아 여는 태그 <p>와 닫는 태그 </p> 한 쌍으로 감싸야 합니다.

단, 다음 두 가지 규칙을 반드시 지켜야 합니다.

  • 두 하위 문자열이 서로 겹치는 경우에는 하나의 단락 태그 쌍으로 함께 감싼다.
  • 태그로 감싸진 두 하위 문자열이 연속해서 나타나는 경우에도 하나로 합친다.

입력 및 출력 예시

예를 들어 입력 문자열과 배열이 다음과 같다고 가정해 보겠습니다.

const str = 'kkkllmm';
const arr = ["kkk","kkl","lm"];

이때 기대되는 출력 결과는 다음과 같습니다.

const output = '<p>kkkllm</p>m';

'kkk'와 'kkl'은 서로 겹치고, 바로 이어지는 'lm'까지 연속되므로 kkkllm 구간 전체가 하나의 <p> 태그로 묶이고, 마지막 'm'만 태그 밖에 남게 됩니다.

구현 코드

이 문제를 해결하는 JavaScript 코드는 다음과 같습니다.

const str = 'kkkllmm';
const arr = ["kkk","kkl","lm"];
var addParagraphTag = (str = [], arr = []) => {
    if(!arr.length){
        return str
    };
    const { length } = str;
    let paraBoolean = new Array(length).fill(false);
    let end = 0;
    for (let i = 0; i < length; i++){
        for (let j = 0; j < arr.length; j++){
            let word = arr[j];
            if (str.startsWith(word,i)) {
                end = Math.max(end, i + word.length);
            };
        }
        paraBoolean[i] = end > i;
    };
    let curr = 0;
    let newStr = '';
    while (curr < length) {
        while(paraBoolean[curr] === false) {
            newStr += str[curr++];
        }
        if (curr >= length) break;
        newStr += '<p>';
        let startBold = curr;
        while (paraBoolean[curr] === true) curr++;
        newStr += str.slice(startBold, curr);
        newStr += '</p>';
    };
    return newStr;
};
console.log(addParagraphTag(str, arr));

코드 동작 원리

핵심 아이디어는 문자열의 각 위치가 단락 태그로 감싸져야 하는지를 먼저 판별한 뒤, 연속된 구간을 하나의 블록으로 묶는 것입니다.

  1. 문자열 길이와 같은 크기의 불리언 배열 paraBoolean을 만들고 모두 false로 초기화합니다.
  2. 각 인덱스 i에서 시작하는 모든 단어를 startsWith()로 검사하여 매칭되면 end를 가장 먼 끝 위치로 갱신하고, paraBoolean[i]에 해당 위치가 태그 범위에 속하는지 저장합니다.
  3. 마지막으로 문자열을 순회하면서 paraBoolean이 false인 문자는 그대로 더하고, true인 연속 구간은 하나의 <p> ... </p> 블록으로 감싸 새로운 문자열을 완성합니다.

실행 결과

코드를 실행하면 콘솔에 다음과 같이 출력됩니다.

<p>kkkllm</p>m