프로그래머스 - 가운데 글자 가져오기

김민준·2023년 10월 3일

코드테스트

목록 보기
27/37

가운데 글자 가져오기

나의 풀이

길이의 절반부터 절반까지(그렇게해야 홀짝 모두 대응 가능하므로)를 새로운 문자열로 반환하면 될것같다.

function solution(s) {
    var answer = '';
    var sArr = [...s]
    const length = s.length

    const low = Math.floor(length/2-0.1)
    const high = Math.ceil(length/2+0.1)

    console.log( low,high)

    for (let i = low ; i < high ; i++){
     answer +=sArr[i]   
        console.log (sArr[i] )
    }

    return answer;
}

다른 사람의 풀이

function solution(s) {
    return s.substr(Math.ceil(s.length / 2) - 1, s.length % 2 === 0 ? 2 : 1);
}

나는 자를 범위의 상한과 하한을 0.1을 더하고 빼서 만들었다.
이 사람은 중간을 반올림하고 1뺀 값을 시작점으로, 그리고 홀수냐 짝순냐에 따라서 자를 갯수를 정했다.

function solution(s) {
    let i = (s.length-1)/2;
    return i%1 ? (s[i-0.5] + s[i+0.5]) : s[i];
}

역시 홀수냐 짝수냐를 구분한뒤 몇글자를 가져올지 정한다.

속도 비교

for문을 돌리는것때문인지 내것이 가장 느리다.

아래와 같이 수정하고 돌려보았다.

// 솔루션0
function sol0(s) {
  var answer = "";
  const length = s.length;

  const low = Math.floor(length / 2 - 0.1);
  const high = Math.ceil(length / 2 + 0.1);

  for (let i = low; i < high; i++) {
    answer += s[i];
  }

  return answer;
}

// 솔루션00
function sol00(s) {
  var answer = "";
  const length = s.length;

  const high = Math.floor(length / 2);

  if (length % 2 === 1) {
    answer = s[high];
  } else {
    answer = s[high - 1] + s[high];
  }

  return answer;
}

// 솔루션1
function sol1(s) {
  return s.substr(Math.ceil(s.length / 2) - 1, s.length % 2 === 0 ? 2 : 1);
}

// 솔루션2
function sol2(s) {
  let i = (s.length - 1) / 2;
  return i % 1 ? s[i - 0.5] + s[i + 0.5] : s[i];
}

//////////////////////////////////////////////////////////

async function runSolutionWithTiming(solutionFn, number1, number2, number3) {
  const startTime = new Date();
  for (let i = 0; i < 10000000; i++) {
    await solutionFn(number1);
    await solutionFn(number2);
    await solutionFn(number3);
  }
  const endTime = new Date();
  const executionTime = endTime - startTime;

  console.log(`${solutionFn.name} 실행 시간: ${executionTime}ms`);
}

async function main() {
  const number1 = "654123165";
  const number2 = "5641231685735213";
  const number3 = "5102345640567432";

  await runSolutionWithTiming(sol0, number1, number2, number3);
  await runSolutionWithTiming(sol00, number1, number2, number3);
  await runSolutionWithTiming(sol1, number1, number2, number3);
  await runSolutionWithTiming(sol2, number1, number2, number3);
}

main()
  .then(() => {
    console.log("모든 실행이 완료되었습니다.");
  })
  .catch((error) => {
    console.error("에러 발생:", error);
  });

  1. for문이 아니라 ... 펼침 연산자 때문에 느려진 것이었다.
  2. nodemon을 사용한뒤 컨트롤+S를 눌러도 상황에 따라서는 옛날의 것으로 작동할 때가 있는듯하다.

test case가 너무 적은 것같아서 늘려보았다.

// 솔루션0
function sol0(s) {
  var answer = "";
  const length = s.length;

  const low = Math.floor(length / 2 - 0.1);
  const high = Math.ceil(length / 2 + 0.1);

  for (let i = low; i < high; i++) {
    answer += s[i];
  }

  return answer;
}

// 솔루션00
function sol00(s) {
  var answer = "";
  const length = s.length;

  const high = Math.floor(length / 2);

  if (length % 2 === 1) {
    answer = s[high];
  } else {
    answer = s[high - 1] + s[high];
  }

  return answer;
}

// 솔루션1
function sol1(s) {
  return s.substr(Math.ceil(s.length / 2) - 1, s.length % 2 === 0 ? 2 : 1);
}

// 솔루션2
function sol2(s) {
  let i = (s.length - 1) / 2;
  return i % 1 ? s[i - 0.5] + s[i + 0.5] : s[i];
}

//////////////////////////////////////////////////////////

async function runSolutionWithTiming(
  solutionFn,
  number1,
  number2,
  number3,
  number4,
  number5
) {
  const startTime = new Date();
  for (let i = 0; i < 10000000; i++) {
    await solutionFn(number1);
    await solutionFn(number2);
    await solutionFn(number3);
    await solutionFn(number4);
    await solutionFn(number5);
  }
  const endTime = new Date();
  const executionTime = endTime - startTime;

  console.log(`${solutionFn.name} 실행 시간: ${executionTime}ms`);
}

async function main() {
  const generateRandomString = (length) => {
    const characters =
      "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    let result = "";
    for (let i = 0; i < length; i++) {
      const randomIndex = Math.floor(Math.random() * characters.length);
      result += characters.charAt(randomIndex);
    }
    return result;
  };

  const number1 = generateRandomString(1000000);
  const number2 = generateRandomString(1000000);
  const number3 = generateRandomString(1000000);
  const number4 = generateRandomString(1000000);
  const number5 = generateRandomString(1000000);

  await runSolutionWithTiming(
    sol0,
    number1,
    number2,
    number3,
    number4,
    number5
  );
  await runSolutionWithTiming(
    sol00,
    number1,
    number2,
    number3,
    number4,
    number5
  );
  await runSolutionWithTiming(
    sol1,
    number1,
    number2,
    number3,
    number4,
    number5
  );
  await runSolutionWithTiming(
    sol2,
    number1,
    number2,
    number3,
    number4,
    number5
  );
}

main()
  .then(() => {
    console.log("모든 실행이 완료되었습니다.");
  })
  .catch((error) => {
    console.error("에러 발생:", error);
  });

실행량을 극단적으로 늘려봤는데 순서의 차이는 없다.

1 > 00 > 0 > 2 의 순이다.

0은 for문 2는 소숫점이 포함되어 있어서 느려지는것같다.
반대로 1은 메모리에 할당하는 과정이 없어서 빠른듯하다.

profile
node 개발자

0개의 댓글