[프로그래머스] 코드 처리하기

루비·2024년 2월 13일
0

알고리즘

목록 보기
1/7

// 코드 1 
// 목표 : 문자열 ret를 return하는 solution 함수를 완성하라.

function solution(code) {
    var answer = '';
    // 시작할 때 mode는 0이며, 
    let mode = 0; 
    // code를 앞에서부터 읽는다.
    for (let i =0; i<code.length; i++) {
        // mode가 0 일때, code[i]가 1이면 mode를 0에서 1로 바꾼다. 
        if(code[i] == 1 && mode === 0) {
            mode =1;
        } 
        // mode가 1일 때 code[i]가 1이면, mode를 1에서 0으로 변경한다. 
        else if (code[i] ==1 && mode===1) {
            mode =0;
        } 
        // mode가 0일 때 code[idx]의 결과가 1이 아니고, 
        // idx가 짝수일 때 ret의 맨 뒤에 code[idx]를 추가
        else if(code[i]!= 1 && mode ===0 && i%2==0) {
            answer+=code[i];
        } 
        // mode가 1일 때 code[idx]의 결과가 1이 아니고, 
        // idx가 홀수일 때 ret의 맨 뒤에 code[idx]를 추가
        else if (code[i] != 1 &&  mode ===1 && i%2!==0) {
              answer+=code[i];
        }
    }
    if(answer.length===0) {
        return "EMPTY"
    }
    return answer;
}
// 리팩토링 및 다른사람 코드 
// 코드 2
function solution(code) {
    var answer = code.replaceAll("1","").split("").filter((val, idx)=> idx%2 === 0).join("");
    return answer.length > 0 ? answer : "EMPTY";
}
// 코드 3 
 function solution(code) {
    let answer = '';
    let mode = 0;

    for (let i = 0; i < code.length; i += 1) {
      if (Number(code[i]) === 1) {
        mode = mode === 1 ? 0 : 1;
      }
      if (Number(code[i]) !== 1 && i % 2 === mode) {
        answer += code[i];
      }
    }
    return answer.length > 0 ? answer : 'EMPTY';
}
// 코드 4
function solution(code) {
    let odd = false
    return Array.from(code).reduce((acc, v, i) => {
        if (v === '1') {
            odd = !odd
            return acc
        }
        return (i % 2 === (odd ? 1 : 0)) ? acc + v : acc
    }, '') || 'EMPTY'
}

네 가지 코드를 성능, 가독성, 그리고 공간 복잡도 측면에서 비교하여 어떤 코드가 더 효율적인지 살펴보겠습니다.

코드 1과 코드 3

  • 시간 복잡도: O(n) — 문자열을 한 번만 순회합니다.
  • 공간 복잡도: O(n) — 결과 문자열 answer는 입력 문자열과 길이가 같을 수 있습니다.
  • 성능: 문자열 연산자 +=를 사용하여 문자열을 구성합니다. JavaScript 엔진에 따라 최적화가 달라질 수 있지만, 많은 중간 문자열을 생성할 수 있어 성능에 영향을 줄 수 있습니다.
  • 가독성: 코드 1은 조건문이 명확하고 이해하기 쉽지만, 코드 3은 Number() 함수 사용으로 인해 약간의 복잡성이 추가됩니다.
  • 특징: 코드 3은 Number() 함수를 사용하여 문자열을 숫자로 변환하는 추가 작업이 있습니다.

코드 2

  • 시간 복잡도: O(n) — 여러 개의 메소드를 체인으로 연결합니다.
  • 공간 복잡도: O(n) — split에 의해 생성된 배열과 결과 문자열이 있습니다.
  • 성능: 여러 내부 반복으로 인해 성능상 불리할 수 있습니다.
  • 가독성: 함수형 프로그래밍의 특성을 반영한 메소드 체이닝이 사용되어 가독성이 좋습니다.
  • 특징: replaceAll, split, filter, join을 사용하여 각 단계에서 전체 배열 또는 문자열을 순회합니다.

코드 4

  • 시간 복잡도: O(n) — Array.from()reduce로 배열을 한 번만 순회합니다.
  • 공간 복잡도: O(n) — reduce로 생성되는 누적 문자열 acc가 있습니다.
  • 성능: reduce를 사용하여 누적값을 관리하는 방식은 문자열 누적에서의 메모리 관리가 더 효율적일 수 있습니다.
  • 가독성: reduce를 사용한 함수형 프로그래밍 스타일로 작성되어 가독성이 좋습니다.
  • 특징: odd 플래그를 사용하여 순회 중에 상태를 토글합니다.

종합 평가:

  • 성능 측면: 코드 4는 reduce를 사용하는 점에서 문자열 누적에서의 성능 이점을 가질 수 있습니다. 코드 1과 코드 3은 += 연산자를 사용하지만, 최신 JavaScript 엔진에서는 이에 대한 최적화가 이루어질 수 있습니다.
  • 가독성 측면: 코드 2와 코드 4는 가독성이 뛰어나며, 특히 코드 4는 로직을 간결하게 표현합니다.
  • 공간 복잡도: 모든 코드가 O(n)을 사용하며, 코드 2는 중간 배열을 생성하기 때문에 실제 메모리 사용량이 더 높을 수 있습니다.

결론: 코드 4가 성능과 가독성의 균형을 잘 맞추고 있으며, 현대 JavaScript 엔진에서의 성능 최적화를 고려했을 때 가장 효율적인 선택일 수 있습니다. 그러나 실제 성능은 실행 환경과 엔진에 따라 달라질 수 있으므로, 크리티컬한 환경에서는 벤치마크


// 리팩토링 코드 
function solution(code) {
    // mode를 0으로 초기화합니다. 이 변수는 문자열 순회 중 '1'을 만날 때마다 토글됩니다.
    let mode = 0;

    // 문자열을 배열로 변환하고, reduce 함수를 사용하여 결과 문자열을 구성합니다.
    return Array.from(code).reduce((acc, v, i) => {
        // 현재 문자가 '1'인 경우, mode를 토글합니다.
        if (v === '1') {
            mode = mode === 1 ? 0 : 1;
            return acc; // '1'은 결과 문자열에 추가하지 않습니다.
        }
        // 현재 문자가 '1'이 아닌 경우:
        // mode가 0일 때는 짝수 인덱스의 문자를,
        // mode가 1일 때는 홀수 인덱스의 문자를 결과 문자열에 추가합니다.
        return (i % 2 === mode) ? acc + v : acc;
    }, '') || 'EMPTY'; // 결과 문자열이 비어있다면 'EMPTY'를 반환합니다.
}

후기

어쩌다보니,, 자바스크립트로 알고리즘을 공부하게 되었고, 근데 예전에 C++로만 문제 풀었지, 자바스크립트는 처음잉교.. 쩝.. 다 까먹어서 걱정.
뭐 언젠간 잘 풀겠지 뭐..

오.. 재밌다.. 유데미 알고리즘 강의 나오는 기법을 참고하여 코드를 작성하고, 그 후 코드 비교하면서 리팩토링 하면서 개념들도 학습하고, 재밌네.. 시간은 오래걸리지만, 내용 학습은 굉장히 좋은듯. 그리고 뭐냐 코드 비교 분석은 내코드 포함 3개까지가 적당한듯.. 최대한 문법이나 쇼트하다고 해서 코드가 빠르게 돌아가는 것도 아니니깐 좋은 코드를 선별하는 눈을 기르도록 노력할것.. ㄴ

profile
개발훠훠

0개의 댓글

관련 채용 정보