알고리즘 문제를 풀면서 알게된 오름차순 정렬과 내림차순 정렬

공식처럼 알고있지만 어떤 원리로 정렬되는지 궁금해 찾아보았다

 

MDN 공식문서를 살펴보자

 

compareFunction이 제공되지 않으면 요소를 문자열로 변환하고 유니 코드 코드 포인트 순서로 문자열을 비교하여 정렬됩니다.

예를 들어 "바나나"는 "체리"앞에옵니다.
숫자 정렬에서는 9가 80보다 앞에 오지만 숫자는 문자열로 변환되기 때문에 "80"은 유니 코드 순서에서 "9"앞에옵니다.

compareFunction이 제공되면 배열 요소는 compare 함수의 반환 값에 따라 정렬됩니다.
a와 b가 비교되는 두 요소라면, compareFunction(a, b)이 0보다 작은 경우 a를 b보다 낮은 색인으로 정렬합니다.
즉, a가 먼저옵니다.compareFunction(a, b)이 0을 반환하면 a와 b를 서로에 대해 변경하지 않고 모든 다른 요소에 대해 정렬합니다.
참고 : ECMAscript 표준은 이러한 동작을 보장하지 않으므로 모든 브라우저(예 : Mozilla 버전은 적어도 2003 년 이후 버전 임)가 이를 존중하지는 않습니다.

compareFunction(a, b)이 0보다 큰 경우, b를 a보다 낮은 인덱스로 소트합니다.

compareFunction(a, b)은 요소 a와 b의 특정 쌍이 두 개의 인수로 주어질 때 항상 동일한 값을 반환해야합니다.
일치하지 않는 결과가 반환되면 정렬 순서는 정의되지 않습니다.

 

...쉽게 풀어쓰면

 

기본적으로 sort() 을 했을 땐 유니코드 포인트 순서대로 정렬한다

9와 80 중 80이 더 큰 숫자이지만 숫자가 아닌 문자로 보면 9보다 8이 더 작기 때문에 80을 일단 앞에 세운다

 

우리가 원하는 오름차순을 위해선 compareFunction(비교함수) 를 넣어주자

 

const arr = [5, 9, 22, 50, 109]
배열 먼저 선언해준다

arr.sort((a,b)=>a-b);
(5) [5, 9, 22, 50, 109]
오름차순

arr.sort((a,b)=>b-a);
(5) [109, 50, 22, 9, 5]
내림차순

a-b 라는 식의 값이

0보다 작을 경우, a 가 b 앞에 오도록 정렬한다

0보다 클 경우, b가 a보다 앞에 오도록 정렬한다

0일 경우, 정렬을 변경하지 않는다

 

이는 a 와 b 의 값을 바꿨을때도 동일한 논리로 연산되어 내림차순이 완성되는 것이다!!

 

 

알고리즘 문제를 풀다보면 Math.floor를 이용할 때가 많다

그런데 parseInt를 사용해도 상관없는 경우가 많았다

그렇다면, 이 둘의 차이는 무엇일까?

 

먼저, Math.floor() 란 간단히 말해 버림이다

 

출처 : MDN https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/floor

 

 MDN 공식 문서의 정의로는 주어진 숫자와 같거나 작은 정수 중 가장 큰 수를 반환한다

 

parseInt 도 마찬가지로 정수를 반환한다

 

 

MDN 공식 문서의 정의로는 문자열 인자를 파싱하여 특정 진수의 정수를 반환한다

이렇듯, parseInt 의 동작방식은 조금 다르다

 

(개인적인 생각인데, 이렇게 문자열 인자로 받고 다시 숫자로 반환하는게

숫자만 계산할때는 불필요한 움직임인가 아닌가 싶다)

 

여기서 차이점을 알 수 있다

parseInt는 문자열 인자를 파싱하기 때문에

 

console.log(parseInt('109 백구'))
109

console.log(parseInt('백구 109'))
NaN

console.log(Math.floor('109 백구'))
NaN

console.log(Math.floor('백구 109'))
NaN

 

'109 백구'과 같이 문자열과 같이 있는 값에서

숫자가 시작하는 부분부터 끝나는 부분까지 저장하여 형변환이 된다

 

반면 '백구 109' 라는 문자열이 먼저오는 값은 숫자가 먼저 나오지 않아서인지 NaN값이 나온다

 

연산속도는 Math.floor가 좀 더 빠르다

 

하지만 둘의 차이는 음수에서도 나타난다

 

console.log(Math.floor('-1.5'))
-2

console.log(parseInt('-1.5'))
-1

console.log(Math.floor('-1.1'))
-2

console.log(parseInt('-1.1'))
-1

 

Math.floor는 앞서 말했듯 숫자의 버림과 같다

 

-1.5 이든, -1.1 이든간에 소수점 자리를 버리면 숫자는 더 큰 숫자가 되어버린다

(-1이 -1.5와 -1.1보다 큰 숫자니까 '버림'이 아닌 '더함'이 되버린다)

 

그래서 더 음수쪽에 가까운 정수인 -2라는 값이 나온다

 

한편, parseInt 는 숫자열을 문자열로 변환후 정수만 도출해내므로 소수점 앞의 숫자열인 -1 만 도출해낸다

 

결론

알고리즘 문제 풀 때 양수일땐 속도가 더 빠른 Math.floor를 사용하되,

문자열과 같이 있거나 음수일땐 parseInt를 사용한다

아니다.

 

Math.floor 와 같으면서 더 빠른 연산자가 있다 ~~

~연산자 를 두개 붙인 ~~ 연산자는 Math.floor 와 똑같은 기능을하면서도 더 빠른 속도로 값을 도출해낸다

 

round, floor, ceil

또, MDN 공식문서에서 재밌는 사실을 알게 되었다

 

round 반올림
floor 내림(버림)
ceil 올림

 

이렇게 자바스크립트 연산자로 반올림, 내림(버림), 올림 하는 법까지 알아보았다

새로운 정보를 알게되어 흥미로웠다

+ Recent posts