자바스크립트 챌린지 2: 단어 뒤섞기

This article was originally posted on my blog. Head over to inspiredwebdev.com for more articles and tutorials. Check out my JavaScript course on Educative to learn everything from ES6 to ES2020.



이 기사에서는 CodeWars의 Scrambles 챌린지를 함께 해결할 것입니다. 여기link에서 찾을 수 있습니다.

함께 작업을 읽어 봅시다.

Complete the function scramble(str1, str2) that returns true if a portion of str1 characters can be rearranged to match str2, otherwise returns false.

Notes:

Only lower case letters will be used (a-z). No punctuation or digits will be included.
Performance needs to be considered
Input strings s1 and s2 are null-terminated.



우리가 보는 첫 번째 예는 다음과 같습니다.

scramble('rkqodlw', 'world') ==> True



첫 번째 솔루션



이 도전에 대한 나의 접근 방식은 두 번째 문자열을 반복하고 그 안에 나타나는 문자의 수에 대한 맵을 만드는 것입니다.

다음과 같이 시작하겠습니다.

const count = {};

str2.split('').forEach((c) => {
    count[c] = count[c] ? count[c]+=1 : 1;
})

빈 객체를 인스턴스화한 다음 str2를 반복하여 문자를 키로 사용하고 개수를 늘려 각 문자가 몇 번 나타나는지 알 수 있도록 했습니다.

카운트를 추적하지 않으면 str1str2의 모든 문자를 포함하지만 한 번만 포함하는 오류가 발생할 수 있기 때문에 이렇게 해야 합니다. str2로 재배열됩니다.
.forEach 에서 string 를 호출할 수 없으므로 먼저 .split('') 를 사용하여 배열로 변환해야 합니다.

이제 첫 번째 예제를 사용하여 코드를 실행하면 다음과 같은 결과를 얻을 수 있습니다.

{ 
    w: 1,
    o: 1,
    r: 1,
    l: 1,
    d: 1 
}

이제 우리가 해야 할 일은 첫 번째 문자열을 반복하고 각 문자에 대해 우리가 만든 이 개체에 나타나는지 확인하는 것입니다. 그렇다면 찾을 때마다 카운트를 1씩 줄입니다.

str1.split('').forEach((c) => {
    !!count[c] && count[c]--
});

여기서 우리는 이전과 동일하게 stringArray로 변환하고 반복합니다. 반복할 때마다 count에 진실한 값이 있는지 확인하고 이 경우 값을 1로 줄입니다. 두 번째 문자열에는 Object에 액세스를 시도할 수 있도록 다른 문자가 포함될 수 있기 때문에 먼저 확인해야 합니다. 존재하지 않는 속성으로.

이 작업을 마치면 count Object의 모든 속성이 이제 0인지 확인해야 합니다.

return Object.keys(count).every((key) => count[key] === 0);
.every 사용 방법을 모르는 경우 find and replace in Array에 대한 내 기사에서 자세한 내용을 읽을 수 있습니다.

모두 합치면 다음과 같이 됩니다.

function scramble(str1, str2) {

    const count = {};

    str2.split('').forEach((c) => {
        count[c] = count[c] ? count[c]+=1 : 1;
    })

    str1.split('').forEach((c) => {
        count[c] && count[c]--;
    });

    return Object.keys(count).every((key) => count[key] === 0);
}



두 번째 솔루션



이제 다른 솔루션으로 시도해 봅시다. str2 에서 문자의 카운트 맵을 만드는 대신 str1 로 해봅시다.

const count = {};

str1.split('').forEach((c) => {
    count[c] = count[c] ? count[c]+=1 : 1;
})

이것은 이전과 동일한 코드이며 방금 str2str1 로 교체했습니다.

이제 str1 를 매핑하는 대신 str2 에서 각 문자의 수를 줄인 다음 모든 키의 값이 0인지 객체를 확인하면 조금 다르게 할 수 있습니다.
str2를 반복할 수 있으며 각 문자에 대해 count 개체의 값을 줄이려고 합니다. str2의 모든 문자에 대해 작업이 성공하면 str1str2 형식으로 재정렬할 수 있음을 의미합니다.

실제로 살펴보겠습니다.

return str2.split('').every((c) => {
    return count[c]--
});

이 코드가 하는 일은 str2 의 각 문자를 반복하여 매번 횟수를 줄이는 것입니다.
str1str2 보다 훨씬 더 길 수 있기 때문에 이 경우 카운트가 0에 도달했는지 여부는 중요하지 않습니다.

여기서 확인하는 것은 return count[c]--가 해당 일치 항목을 찾지 못하거나 음수 값으로 이동하여 falsestr2보다 해당 문자가 더 많이 포함됨을 의미하는 음수 값으로 이동하여 str1를 반환하지 않는다는 것입니다.

완전한 솔루션은 다음과 같습니다.

function scramble(str1, str2) {

    const count = {};

    str1.split('').forEach((c) => {
      count[c] = count[c] ? count[c]+=1 : 1;
    })

    return str2.split('').every((c) => {
        return count[c]--
    });

}

이 문제를 해결하는 다른 많은 방법이 있습니다. 의견에 귀하의 방법을 알려주십시오.

이러한 유형의 콘텐츠가 마음에 드셨다면 댓글로 알려주시면 더 많은 콘텐츠를 만들겠습니다.




ES6에서 ES2020까지 JavaScript에 대한 모든 것을 배우고 싶다면 Github에서 무료로 읽을 수 있는 제 책을 확인하세요. 과정도 진행 중입니다 Educative.



좋은 웹페이지 즐겨찾기