백준 2480번
- 문제
- 풀이 1
처음 생각나는데로 풀이한 결과이다.
- 풀이 2
세 숫자가 전부 다를 경우, for문을 통해 처리
하기위해
int 배열을 사용해봤다. 유의미한 차이는 없다.
솔직히 백준의 속도
측정은 신뢰가 안간다.
똑같은 코드도 제출 시간에 따라 다른 속도
가 나온다.
따라서 무슨 코드가 더 빠르고 유용한지 알아보기는
적절하지 않다.
데이터량이 적었을 경우와 많을 경우에도 차이가 날 수
있기 때문에 기초 지식이 없이백준의 결과
로 성능, 속도
를
판단하기는 힘들다.
사실 처음에는 for문의 조건으로 countTokens를 이용했었다.
근데 이를 실행하면 올바르게 동작하지 않는다.
조건문이 틀렸는지, 코드에 오타가 있는건지 등
정상 작동하지 않는 이유가 무엇인지 고민했다.
그러다보니 위의 실행 결과가 a, b, c 모두
같을 경우의 조건을 실행하는 것이 아닌,
a, b, c 중 두개가 같은 경우의 조건을 실행
하고 있다는 것을 알게됐다.
이후 계속된 고민과 테스트 끝에 이유를
알 수 있었다.
-
countTokens라는 함수는
반환할 수 있는 토큰
의
총 개수를 리턴한다. -
for문의 동작원리를 생각해보면 한번 실행 후
증감이 이루어지고, 두번째 위치한 조건
i < st.countTokens()
을 검사해 조건에
부합하면 실행하는 방식을 반복한다.
즉, 위 출력결과를 보면 for문이 한번 실행될 때마다
nextToken을 통해 토큰이 하나씩 출력
되기 때문에,
총 토큰의 개수
가 하나씩 줄어들 수 밖에 없다.
for문이 한번 돌고 i < st.countTokens()
라는
조건을 확인할 때, st.countToken(총 토큰 수)은
-1된 상태이다.
다시말해, for문의 조건이 for문이 한번 돌 때마다
변한다는 것이다.
결과적으로 위 코드는 for문을 두번밖에 실행
하지
않게되며, 2 2 라는 숫자가 num[0], num[1]에
들어가게 된다. num[2]에는 아무 값도 들어오지 않아
자바가 배열 생성 시 세팅한 초기값 0이 들어있는
상태이다. 결국 num[0], num[1], num[2]에는 2, 2, 0
이라는 값이 들어있기 때문에두 수가 동일한 조건문을 실행
하게 되는 것이다.
이해가 어려운 사람을 위해 for문의 동작을 설명해보겠다.
처음 for문의 코드를 실행할 때 countTokens의 값은
3이다. 현재 i는 0이기 때문에 0 < 3 조건을 만족하고
코드가 실행된다.
코드가 실행된 후 i는 1로 증가한다. 그 다음
i < st.countTokens 조건을 검사하는데, 이 때
st.countTokens의 값은 2이다. 왜냐면 이전 실행문에서
st.nextToken이라는 코드로 토큰 하나를 반환 받았기
때문에 총 토큰수가 3에서 2로 바뀐 것이다. 현재
i는 1이고 st.countTokens은 2이기 때문에 조건을
만족해 코드가 실행된다.
코드가 실행된 후 같은 방식으로 i는 2로 증가하지만
st.countTokens의 값은 1이다. 그렇다면 조건식
검사 시 2 > 1는 false이기 때문에 코드를 실행하지
않고 for문을 나오게 된다.
즉, 해당 for문을 돌릴때 countTokens를 통해 조건을
작성하는 것은 잘못된 설계인 것이다.
while + hasMoreTokens으로 구현해도
유의미한 차이는 없어보인다.
forEach로도 해보고 싶었지만 무슨 매개변수를 사용해야 할지 몰라서
못했다. 아시는 분 계시면 공유좀 부탁드립니다.
- 풀이 3
if 문의 조건을 세 숫자가 같을 경우에만 논리
연산자
를 사용하고, 나머지는 사용하지 않도록
하나씩 분리했다.
연산하는 코드는 두 개의 함수로 만들었다.
속도
에 유의미한 차이는 없다.
솔직히 여러 방식으로 코드를 짜고 테스트
해보는 이유가 성능, 속도
비교를 하고 싶기
때문인데, 앞서 말했다시피 백준 결과만으로는
알기 어렵다.
추후에 고수가 된다면 이 궁금증들을 해결해보고
싶다. 지금은 여러 방식으로 코드를 짜보고,
그 과정에서 모르는 부분을 학습하는것을 우선 시
하고있다.
추가적으로 위 문제를 if문 없이 풀이 가능한 방법을 아시면
공유 부탁드리겠습니다.
- 다른 사람 풀이
위 링크의 코드를 보면 아래와 같다.
여기서 다섯가지 분기가 아닌 네가지 분기를 만들었다.
a == b
와 a == c
는 a를 공통으로 갖고 있기 때문에
묶고, b == c
만 따로 처리해주었다. 또한 자바 API
Math 클래스의 max 메소드를 활용하여 최댓값을 구했다.
근데 윗 코드에서 모두 같다는 것을 비교할 시
a == b
, a == c
, b == c
세번을 작성한 이유는
모르겠다. a와 b가 같고, a와 c가 같으면 b와 c는
자동으로 같다고 보기에 하나는 빼도 될듯하다.
if 분기가 4번이고, 5번인 한번의 차이는 속도차이가
별로 안날 것 같은데, 자바 API를 사용하면 속도 차이
가
있을지에 대해 궁금해서 돌려봤다.
역시 코드가 짧고 내용이 적어서 유의미한 결과를
얻을 수는 없었다. 해당 결과는 윗 코드를 Buffered
Stream
을 이용해 입력받고 테스트 해본 결과이다.
= Plus, Tip =
[switch vs if]
switch문으로 구현 가능한 것은 모두 if문으로 구현 가능하다.
하지만 역은 성립하지 않는다. 그렇다면 if문으로 모든 조건을
처리할 수 있으니 편하게 if문만 쓰면 될까?
찾아보니 조건의 숫자가 3~4개 이하라면 if문이 더 빠르고,
조건이 많아지면 switch문이 빠르다. 따라서 조건이 많은
경우에 switch문을, 조건이 적거나 switch문으로
구현이 불가한 경우에 if문을 사용하면 좋을 것 같다.
하지만 이로인한 성능차이 보다 코드의 가독성, 의미에
따라 if, switch를 선택하는 것이 좋다. 분야에 따라
다르지만 대부분의 경우에 if, switch 중 무엇을 썼느냐에
따라 심각한 문제나 에러, 성능 저하가 일어나진 않기
때문이다.
추가적으로 랜덤 값이 입력될 경우 switch문이 if문 보다
처리속도가 훨씬 빠르다. 반면 switch문은 case에 없는 값이
들어오면 속도가 현저하게 느려진다. if문은 조건이 바로
검색될 시 처리속도가 빠르므로 사용자가 자주 사용하는 기능
을 상단에 먼저 작성해야 한다. 여러 기능을 비슷하게 사용한다면
switch문을 사용하는게 좋다.
정리하자면,
if문은 많이 쓰이는 기능(범용성이 높은)에 대한 조건을
상단부에 먼저 작성해줌으로써 성능을 개선할 수 있다.
조건의 수가 적을 경우 if, 많을 경우 switch를 추천한다.
값이 연속되거나 여러 조건이 유사한 빈도로 사용되면
switch를 사용하는게 좋다. 하지만 성능상 차이는
미비할 수도 있으니 가독성, 의미에 더 중점을 두어야한다.
[if 반복 사용 vs if-else if-else]
if()
if()
라던지
if(){}
if(){}
로 코드를 작성하는게 가독성도 좋아보이고 깔끔하며
필자 기준으로는 기존에 접해보지 못한 방식이라 앞으로
코드를 이런식으로 짤 예정이였다.
하지만 찾아보니 위와 같은 방식은 필요한 상황에만
써야하는 것이지 if-else if-else를 대신해 무조건
사용할 수는 없다는 것을 알 수 있었다.
다수의 if를 통해 조건을 작성하게되면 100개의 조건이 있을
시 100번의 검사가 이루어지게된다. 반면 if-else if-else를
사용하게 되면 실행 중 해당하는 조건을 찾으면 나머지는
검사하지 않게된다.
Author And Source
이 문제에 관하여(백준 2480번), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@onestep/baekjoon-2480저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)