숨어있는 숫자의 덧셈 (1)

HS K·2023년 2월 17일
0
post-custom-banner

문제설명

문자열 my_string이 매개변수로 주어집니다. my_string안의 모든 자연수들의 합을 return하도록 solution 함수를 완성해주세요.

제한사항

  • 1 ≤ my_string의 길이 ≤ 1,000
  • my_string은 소문자, 대문자 그리고 한자리 자연수로만 구성되어있습니다.

내가 쓴 답

function solution(n) {
    let result = 0
    let changed = n.split("")
    
    for(let i=0; i<changed.length; i++) {
      if (typeof(parseInt(changed[i]))="number") {
        return changed[i]
      }
      else if (typeof(parseInt(changed[i]))="string") {
       return 0 
      }
      return result += changed[i]
    }
}
console.log(typeof(solution(n)))

※ 참고로 틀린 답이다. 어디가 틀렸을까?

  1. for 루프에 대한 반복자 i가 선언되지 않았다. for 루프를 실행하기 전에 let i = 0과 같이 i를 초기화해야한다. (초기화의 개념을 짚을 수 있었다)

  2. return 문이 if 문 내부에 있기 때문에 첫 번째 문자만 확인하고 결과를 반환한다. 따라서 for 루프가 종료되기 전에 결과를 반환할 수 있다.

  • return의 위치를 어디로 잡아야할지 헷갈렸다.

2차 수정

function solution(n) {
  let result = 0;
  let changed = n.split("");
  
  for(let i=0; i<changed.length; i++) {
    if (typeof parseInt(changed[i]) === "number") {
      result += parseInt(changed[i]);
    }
    else {
      return 0;
    }
  }
  
  return result;
}
  1. parseInt()의 오용
    여태까지 parseInt로 문자를 숫자로 변환하고, 그 이후에 사칙연산을 했을때
    형변환을 하더라도 parseInt(q)+parseInt(3)의 연산은 NaN이 나오는 것으로 알고 있었기 때문에 당연히 나는 parseInt(q)가 문자이기 때문이라고 생각했었는데, 잘못알고 있었다.
    typeof parseInt(changed[i])의 결과는 항상 "number"이다.
    그러므로 typeof parseInt(changed[i]) === "number"는 항상 true이므로 숫자가 아닌 문자를 체크할 수 없다.

대신 isNaN() 함수를 사용하여 각 문자가 숫자인지 아닌지를 체크할 수 있다.

3차 수정

function solution(n) {
  let result = 0;
  let changed = n.split("");
  
  for(let i=0; i<changed.length; i++) {
    let num = parseInt(changed[i]);
    if (!isNaN(num+0)) { 
      result += num;
    }
    else {
      return 0;
    }
  }
  return result;
}

최종 수정한 답

function solution(my_string) {
  let changing = my_string.split("");
  let changed = changing.join(" ")
  let regex = /\d+/g; 
  let matches = changed.match(regex); 
  let sum = 0;
  
  for (let i = 0; i < matches.length; i++) {
    sum += parseInt(matches[i]);
  }
  
  return sum;
}

여러종류의 풀이 보기

1번

function solution(my_string) {
    let sum = 0;
    for (const ch of my_string) {
        if (!isNaN(ch)) sum += +ch;
    }
    return sum;
}

2번

function solution(my_string) {
    return my_string.replaceAll(/[^\d]/g, '').split('').map(v=>+v).reduce((a,v)=>a+v,0);
}
  • +를 이용하여 형변환을 해주는 방법에서 센스가 돋보였다.

후기

  1. 배열의 특성상 모든 요소는 문자형이기 때문에 배열의 모든 요소를 parseInt로 형변환 후에 문자형이 숫자형으로 된 경우와 원래 형태가 숫자인 문자가 배열의 정의에 의해 문자가 숫자로 돌아오는 경우를 어떻게 구분해야하는지 고민을 많이했다.

예를 들어 let my_string = "aAb1B2cC34oOp"라고 했을때, split("")함수를 통해

let changing = ['a', 'A', 'b', '1','B', '2', 'c', 'C','3', '4', 'o', 'O','p']

를 만들었다면, 반복문을 통해 changing의 요소들을 모두 숫자형으로 형변환 시켜준다면 changing[0]과 changing[3]은 모두 숫자형이지만, 실제로 이 둘은 연산을 했을땐 NaN이 나오므로 형변환을 하더라도 "진짜 숫자"를 찾아야한다.

  1. 1차 수정과 2차 수정때 typeof와 isNaN()도 시도해보고, 3차 수정때는 도저히 답이 나오지 않아 정규표현식으로 문제를 풀었다.

  2. GPT를 쓰니 내가 무엇을 모르는지 파악하는데 걸리는 시간이 매우 단축된다.

  3. 문제를 풀때 자꾸 고려해야할 상황을 자꾸 고려하지 않는다. 아마 이 부분을 자꾸 생각해줘야 사고력이 늘 것 같다.

profile
주의사항 : 최대한 정확하게 작성하려고 하지만, 틀릴내용이 있을 수도 있으니 유의!
post-custom-banner

0개의 댓글