[문제풀이]4가지 풀이로 알아본 숫자 뒤집기(음수포함)

개발.log·2021년 9월 16일
1
post-thumbnail

reverse 함수에 정수인 숫자를 인자로 받습니다. 그 숫자를 뒤집어서 return해주세요.
x: 숫자 return: 뒤집어진 숫자를 반환!
예들 들어, x: 1234 return: 4321
x: -1234 return: -4321
x: 1230 return: 321

오늘의 문제! (사실은 엊그제)
뒤집어진 숫자 반환하기! 하지만 -(음수)면 마이너스가 그대로 맨 앞에 와야한다.

첫번째 풀이

const reverse= x => {
//1. 
  let arr =x.toString().split('').reverse();
//2.
 	 if(arr[arr.length-1]==='-'){
  	  arr.unshift('-')
  	  arr.pop()
 	 }
  
//3.  
  let result=arr.join('')
//4.
  return parseInt(result)
}
  1. 먼저 배열의 메서드인 reverse 메서드를 쓰기 위해서 x를 문자로 바꾸고, split으로 한글자씩 쪼개서 배열에 담아줬다. 그후, reverse메서드 실행
  2. 만약 x가 -1234(음수) 였으면 ["4","3","2","1","-"] 로 담아졌을 것이다. 그렇다면 맨뒤에 "-"를 빼고, 맨 앞에 "-"를 붙여주었다.
    그렇다면 ["-","4","3","2","1"]이 되었을 것이다.
  3. join 메서드로 배열의 모든 요소를 연결해 하나의 문자열로 만들었다.
  4. pserInt를 이용해 문자열을 숫자로 변환하여 리턴해주면 끝!

하지만 마음에 들지 않는다.
어디선가 봤는데, unshift/shift 메서드는 배열의 맨 앞 요소를 삭제/삽입 하기 위해 모든 배열을 건들여 한칸씩 미루거나 당겨와야된다.
따라서 pop,push 등, 맨 뒤 요소 하나만 건들여 삽입하는 행위에 비해 너무 비효율적이고 성능에 안좋다는 것이다.
배열이 이렇게 짧을때는 문제가 안되지만, 배열이 길어 질수록 성능이 떨어진다. 지양하는게 좋다.

두번째 풀이

그래서 순수 for문 / if문으로만 풀어 봤다.

const reverse=x=>{
    let result=""
    let real=""
   //1.
    let string=x.toString()
    //2.
    if(string[0]=="-"){
        for(let i=string.length-1;i>=1;i==){
            result+=stirng[i]
     //3.
            real="-"+result
             }
    }else{
     //4.
          for(let i=string.length-1;i>=0;i--){
            real+=string[i]
            }
    }
      //5.
            return parseInt(real)
 }
  1. for를 사용하여 요소를 순회하기 위해, x(숫자)를 toString을 사용하여 문자로 바꿔주고,
  2. 만약에 첫번째 문자가 -(음수)라면 for문이 맨 뒷자리부터 시작하여 맨앞자리("-")전 까지 누적하며 result변수에 담아준다.
  3. 음수였으니까 다시 문자 "-"를 붙인 새로운 변수를 생성하며 마무리.
  4. 로직은 2,3번과 동일 하나 양수였으므로 -를 붙이지 않고 real 그대로를 반환한다.
  5. 문자열 real을 parseInt로 숫자 변환하며 리턴.

단점:무슨 의도로 작성했는지 코드의 의미가 전혀 읽히지 않아 가독성이 매우 떨어진다.

세번째 풀이

const reverse = x => {
  // 여기에 코드를 작성해주세요.
  if(x<0){
    let numArray = String(x*(-1)).split("")
    return numArray.reverse().join("")*(-1)
  }
    let numArray = String(x).split("")
    return parseInt(numArray.reverse().join(""))
}
  1. x가 음수면 양수로 변환한후 문자로 변환하고, split으로 문자를 배열로 변환한다.
  2. reverse로 배열을 뒤집고 다시 join으로 문자로 변환한다. 문자에 *를 해주어 숫자로 자동 형변환한다.(이 과정에서 다시 음수로 바꿔주기 위해 *-1)
  3. 1,2번과 똑같은 로직이지만 음수를 양수로 변환/ 양수를 음수로 다시 변환하는 과정만 빠졌다.

shift,unshift도 안쓰고, 가독성도 나쁘지 않지만 뭔가 좀 더 개선하고 싶은 욕심이 들었다.

네번째 풀이

const reverse = x => {
  //1.  
  const arr = Math.abs(x).toString().split("");
  //2.
  let result = Number(arr.reverse().join(''));
  //3.
  return (x > 0) ? result : result * -1;
}

네번째 풀이에서야 abs 함수를 알게되었다. 양수/음수 변환해주고, 그에 따라 값도 다르게 리턴해주는게 왠지 코드가 길어지고 구려보였는데, 이 메서드와 삼항연산자를 쓰니까 확 줄었다.

[MDN에서 정의하는 abs 함수!]

Math.abs() 함수는 주어진 숫자의 절대값을 반환합니다. x가 양수이거나 0이라면 x를 리턴하고, x가 음수라면 x의 반대값, 즉 양수를 반환합니다.

  1. 먼저 양수든 음수든 절대값으로 바꾼 다음에 문자로 변환하고, split으로 배열에 담는다.
  2. 담긴 배열을 reverse 메서드로 뒤집고 다시 join으로 문자 변환한다음, 다시 숫자로 변환한다.
  3. 만약에 주어진 x가 양수면 result 그냥 반환. 음수였을 시, 2번에서 만든 result변수에 *-1을 해주어 반환

오..코드의 의도도 보이고, 간결해져서 가독성이 높아졌다. 마음에 든다.^^ 이 코드로 최종 결정~ 제출완.

참고자료:
MDN | Array.prototype.join()
MDN|Array.prototype.unshift()
MDN | Array.prototype.pop()
MDN | Array.prototype.push()
MDN | Math.abs()

profile
Think Big Aim High Act Now

0개의 댓글