코딩기록

replace) 소문자 'l'로 만들기 / a < z, 오름차순 정렬, 단일문자 보다 작으면 문자열 변경 - for, for...of, forEach, 정규표현식, map, filter 본문

프론트/JS)코딩테스트

replace) 소문자 'l'로 만들기 / a < z, 오름차순 정렬, 단일문자 보다 작으면 문자열 변경 - for, for...of, forEach, 정규표현식, map, filter

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

문제 설명

알파벳 소문자로 이루어진 문자열 str이 주어집니다. 알파벳 순서에서 "l"보다 앞서는 모든 문자를 "l"로 바꾼 문자열을 return 하는 solution 함수를 완성해 주세요.


제한사항

  • 1 ≤ str ≤ 100,000
    • str은 알파벳 소문자로 이루어진 문자열입니다.

입출력 예

str result

"abcdevwxyz" "lllllvwxyz"
"jjnnllkkmm" "llnnllllmm"

입출력 예 설명

입출력 예 #1

  • 0 ~ 4번 인덱스의 문자 "a", "b", "c", "d", "e"는 각각 "l"보다 앞서는 문자입니다. 따라서 "l"로 고쳐줍니다.
  • 그 외의 문자는 모두 "l"보다 앞서지 않는 문자입니다. 따라서 바꾸지 않습니다.
  • 따라서 "lllllvwxyz"을 return 합니다.

입출력 예 #2

  • 0번, 1번, 6번, 7번 인덱스의 문자 "j", "j", "k", "k"는 각각 "l"보다 앞서는 문자입니다. 따라서 "l"로 고쳐줍니다.
  • 그 외의 문자는 모두 "l"보다 앞서지 않는 문자입니다. 따라서 바꾸지 않습니다.
  • 따라서 "llnnllllmm"을 return 합니다.
const solution = str => {
  // do something
};

console.log(solution('abcdevwxyz')); // 'lllllvwxyz'
console.log(solution('jjnnllkkmm')); // 'llnnllllmm'

 

 


풀이

이 문제는 값을 변경하거나 대체하는 문제라서 필터링 하는 용도인 filter() 메서드가 적합하지 않다.
filter()는 요소를 남길지 여부를 결정하는 데 사용되며, 
값을 변경하고자 한다면 map()을 사용하는 것이 적합하다.

 

1번 풀이 for문

for 루프로 문자열str을 순회해서

l보다 문자가 작을 경우 'l'을 추가하고 그렇지 않으면 원래 문자를 추가함.

// 1번 풀이 for문
const solution1 = (str) => {
  const target = 'l';
  let src = '';
  for (let i = 0; i < str.length; i++) {
    str[i] < target ? src += 'l' : src += str[i]
  };
  return src;
};
console.log(solution1('abcdevwxyz')); // 'lllllvwxyz'
console.log(solution1('jjnnllkkmm')); // 'llnnllllmm'

 

 

2번 풀이 for...of

for와 동일.

// 2번 풀이 for...of
const solution2 = (str) => {
  const target = 'l';
  let src = '';
  for (const c of str) {
    c < target ? src += 'l' : src += c;
  }
  return src;
};
console.log(solution2('abcdevwxyz')); // 'lllllvwxyz'
console.log(solution2('jjnnllkkmm')); // 'llnnllllmm'

 

 

3번 풀이  forEach

forEach

주로 if문이 들어가는 자리에 삼항연산자를 쓰는데 if문으로 변경하자면 아래와 같다

if (c < target) {
      src += 'l';
    } else {
      src += c;
    }

 

처음엔 삼항연산자가 어려워 보여도 한번 눈에 보이면 if... else문보다 훨씬 가독성이 좋다(짧은 코드일수록 더).

// // 3번 풀이 forEach
const solution3 = (str) => {
  const target = 'l';
  let src = '';
  [...str].forEach(c =>
    c < target ? src += 'l' : src += c
  );
  return src;
};
console.log(solution3('abcdevwxyz')); // 'lllllvwxyz'
console.log(solution3('jjnnllkkmm')); // 'llnnllllmm'

 

 

4번 풀이 정규표현식 regExp + replace

정규표현식이 처음에 규칙을 익히는데 시간이 걸려도 한번 익히면 가장 편한 코딩 방법이라고 생각한다.

여러 줄로 풀어야 할 문제를   replace(/[a-k]/g, 'l')    이렇게 replace() 메서드와 정규표현식 몇 자로 끝냈다.

a~k를 ㅣ로 변경한다는 뜻이다.

// 4번 풀이 정규표현식 regExp - a~k를 l로 변경
const solution4 = (str) => {
  return str.replace(/[a-k]/g, 'l');
};
console.log(solution4('abcdevwxyz')); // 'lllllvwxyz'
console.log(solution4('jjnnllkkmm')); // 'llnnllllmm'

 

 

5번 풀이  map

 다른 코드의 아이디어와 동일하다 현재 순회하는 문자인c 가 target보다 작으면 target으로 바꾸고 아니면 현재 문자를 반환한다. 

// 5번 풀이 map
const solution5 = (str) => {
  const target = 'l';
  return [...str].map(c =>
    c < target ? target : c
  ).join('');
};
console.log(solution5('abcdevwxyz')); // 'lllllvwxyz'
console.log(solution5('jjnnllkkmm')); // 'llnnllllmm'

 

 

6번 풀이 reduce

reduce로 이전까지 누적된 값 acc에 현재 문자 cur가 target보다 작은 경우에는
target을, 그렇지 않으면 c를 더하여 새로운 누적 값을 만들어냄.

 

삼항연산자로 묶고 그 앞에 acc + 를 하는 부분을 이해 못해서 시간이 걸렸다.

역시 reduce는 연습이 더 필요하다.

// 6번 풀이 reduce
const solution6 = (str) => {
  const target = 'l';
  return [...str].reduce((acc, cur) => acc + (cur < target ? target : cur), '');
};
console.log(solution6('abcdevwxyz')); // 'lllllvwxyz'
console.log(solution6('jjnnllkkmm')); // 'llnnllllmm'

 

 

참고

나, 쳇지피티

 

 

 

반응형
Comments