코딩기록

replace) 옹알이 (1) / 문자배열과 동일한 문자 카운트, 개수 구하기 - forEach + 유효성검사, filter, .length 본문

프론트/JS)코딩테스트

replace) 옹알이 (1) / 문자배열과 동일한 문자 카운트, 개수 구하기 - forEach + 유효성검사, filter, .length

뽀짝코딩 2024. 9. 25. 21:28
728x90

머쓱이는 태어난 지 6개월 된 조카를 돌보고 있습니다. 조카는 아직 "aya", "ye", "woo", "ma" 네 가지 발음을 최대 한 번씩 사용해 조합한(이어 붙인) 발음밖에 하지 못합니다. 문자열 배열 babbling이 매개변수로 주어질 때, 머쓱이의 조카가 발음할 수 있는 단어의 개수를 return하도록 solution 함수를 완성해주세요.


제한사항

  • 1 ≤ babbling의 길이 ≤ 100
  • 1 ≤ babbling[i]의 길이 ≤ 15
  • babbling의 각 문자열에서 "aya", "ye", "woo", "ma"는 각각 최대 한 번씩만 등장합니다.
    • 즉, 각 문자열의 가능한 모든 부분 문자열 중에서 "aya", "ye", "woo", "ma"가 한 번씩만 등장합니다.
  • 문자열은 알파벳 소문자로만 이루어져 있습니다.

입출력 예

babbling result

["aya", "yee", "u", "maa", "wyeoo"] 1
["ayaye", "uuuma", "ye", "yemawoo", "ayaa"] 3

입출력 예 설명

입출력 예 #1

  • ["aya", "yee", "u", "maa", "wyeoo"]에서 발음할 수 있는 것은 "aya"뿐입니다. 따라서 1을 return합니다.

입출력 예 #2

  • ["ayaye", "uuuma", "ye", "yemawoo", "ayaa"]에서 발음할 수 있는 것은 "aya" + "ye" = "ayaye", "ye", "ye" + "ma" + "woo" = "yemawoo"로 3개입니다. 따라서 3을 return합니다.
const solution = babbling => {
  // do something
};

console.log(solution(['aya', 'yee', 'u', 'maa', 'wyeoo'])); // 1
console.log(solution(['ayaye', 'uuuma', 'ye', 'yemawoo', 'ayaa'])); // 3

풀이

옹알이 문제로 인해 정규표현식의 중요성을 알게됐다.

 

1번 풀이 forEach + 정규표현식

정규표현식을 이용하면 코드가 간결해진다.

// 1번 풀이 forEach + 정규표현식
const solution1 = babbling => {
  const word = ["aya", "ye", "woo", "ma"];
  const regExp = /^(aya|ye|woo|ma)+$/;

  // 중복된 음절 금지.
  //단순히 어디든지 ()안의 패턴이 연속적으로 등장하는지 확인 시작^, 끝$ 표시 없어도 됨.
  const noRepeatRegex = /(ayaaya|yeye|woowoo|mama)/;
  let count = 0;
  babbling.forEach(word => {
    if (regExp.test(word) && !noRepeatRegex.test(word)) {
      count++;
    }
  });
  return count;
};
console.log(solution1(['aya', 'yee', 'u', 'maa', 'wyeoo'])); // 1
console.log(solution1(['ayaye', 'uuuma', 'ye', 'yemawoo', 'ayaa'])); // 3

 

2번 풀이 

일치하는 문자를 찾아 공백으로 바꾸고

trim으로 앞 뒤 공백 제거 후 공백으로만 이뤄진 요소의  길이를 찾아 반환.

const solution2 = babbling => {
  const arr = [];

  for (const c of babbling) {
    arr.push(
      c.replace('aya', '').replace('ye', '').replace('woo', '').replace('ma', '')  // [' ', ' e', 'u', ' a', 'w oo']
    );
  }
  return arr.filter(c => c.trim() === '').length; // 공백으로만 이뤄진 요소의 길이를 찾아 반환.
};
console.log(solution2(['aya', 'yee', 'u', 'maa', 'wyeoo'])); // 1
console.log(solution2(['ayaye', 'uuuma', 'ye', 'yemawoo', 'ayaa'])); // 3

 

3번 풀이 

const solution3 = babbling => {
  let count = 0;

  for (const str of babbling) {
    if (str.replace(/aya|ye|woo|ma/g, '') === '') count += 1;
  }
  return count;
};
console.log(solution3(['aya', 'yee', 'u', 'maa', 'wyeoo'])); // 1
console.log(solution3(['ayaye', 'uuuma', 'ye', 'yemawoo', 'ayaa'])); // 3

 

 

4번 풀이 

const solution4 = babbling => {
  return babbling.filter(c => c.replace(/aya|ye|woo|ma/g, '') === '').length;
};
console.log(solution4(['aya', 'yee', 'u', 'maa', 'wyeoo'])); // 1
console.log(solution4(['ayaye', 'uuuma', 'ye', 'yemawoo', 'ayaa'])); // 3

 

 

5번 풀이 filter, map, reduce

정규표현식 없이 풀면 코드가 길어진다. 어려워서 쳇지피티한테 물어봤다.

 

// 5번 풀이 filter , map, reduce
const solution5 = (babbling) => {
  // 사용할 수 있는 유효한 음절 배열
  const validSyllables = ["aya", "ye", "woo", "ma"];

  // 단어가 유효한지 검사하는 함수
  const isValidWord = (word) => {
    let previousSyllable = ""; // 이전 음절을 저장할 변수
    let isValid = true;        // 단어의 유효성을 추적하는 플래그

    // 단어가 남아 있고 유효할 때까지 반복
    while (word.length > 0 && isValid) {
      let found = false; // 유효한 음절을 찾았는지 여부를 나타내는 플래그

      // 유효한 음절 리스트(validSyllables)에서 음절을 하나씩 검사
      for (const syllable of validSyllables) {
        // 단어가 현재 음절(syllable)로 시작하는지 확인
        if (word.startsWith(syllable)) {
          // 같은 음절이 연속으로 사용되었는지 검사, 중복방지
          if (syllable === previousSyllable) {
            isValid = false; // 연속된 음절이면 유효하지 않다고 판단
            break;           // 반복문 탈출
          }
          // 유효한 음절을 발견한 경우
          // 현재 단어에서 해당 음절을 제거하고(word를 자르고)
          word = word.slice(syllable.length);
          // 이전 음절을 현재 음절로 업데이트
          previousSyllable = syllable;
          found = true; // 유효한 음절을 찾았으므로 true로 설정
          break; // 반복문 탈출 (한 번에 하나의 음절만 처리)
        }
      }

      // 유효한 음절을 찾지 못한 경우, 더 이상 유효하지 않은 단어로 판단
      if (!found) {
        isValid = false;
      }
    }

    // 단어가 비어 있고, 유효한 상태이면 true 반환
    return isValid && word.length === 0;
  };

  // 유효한 단어만 필터링하여 개수를 반환
  return babbling.filter(isValidWord).length;
  // return babbling.map(isValidWord).filter(Boolean).length;
  // return babbling.reduce((count, word) => count + (isValidWord(word) ? 1 : 0), 0);
};
console.log(solution5(['aya', 'yee', 'u', 'maa', 'wyeoo'])); // 1
console.log(solution5(['ayaye', 'uuuma', 'ye', 'yemawoo', 'ayaa'])); // 3

 

주요 아이디어:

  • 각 단어에서 주어진 음절("aya", "ye", "woo", "ma")을 하나씩 찾아서 제거해 나가는 방식입니다.
  • 음절을 제거한 후, 그 단어가 모두 비어 있다면 그 단어는 유효한 단어입니다.
  • 같은 음절이 연속으로 등장하는 경우를 방지하기 위해 음절을 처리할 때 이전 음절을 기록합니다.

해결 방법

  1. 음절 배열 생성:
    • 허용된 음절들을 배열로 정의합니다.
  2. 각 단어를 처리:
    • 각 단어에서 허용된 음절을 찾고, 발견되면 해당 음절을 제거합니다.
    • 음절이 순차적으로 사용되었고, 다른 불필요한 문자가 남지 않았는지 확인합니다.
  3. 연속된 음절 방지:
    • 이전에 사용된 음절을 기록하고, 동일한 음절이 연속해서 나오면 그 단어는 무효 처리합니다.

 

 

 

 

 

참고

나, 쳇지피티

 

 

반응형
Comments