백준 2480번

YJ·2022년 3월 22일
0
post-thumbnail

- 문제




- 풀이 1

문제를 보고 생각나는대로 풀이해봤다.




- 풀이 2

세 숫자가 전부 다른 경우 for문을 통해 처리하기 위해 int 배열을 사용해봤지만 유의미한 차이는 없다.



처음에는 이와 같이 배열에 값을 할당하는 과정에서 countTokens을 사용했었다. 2 2 2를 입력 했을 때, 세 숫자가 같은 경우에 해당하는 조건이 실행돼 12000이 출력될 것으로 예상했다. 하지만 결과는 두 숫자가 같은 경우에 해당하는 조건이 실행된 1200이 출력됐다.



위와 같은 코드로 테스트를 해보면 countTokens에 대해 이해하고, 오류가 발생한 이유를 알 수 있다.


  1. countTokens은 현재 반환할 수 있는 토큰의 총 개수를 리턴한다.

  2. for문이 한 번 동작할 때마다 st.nextToken()을 통해 토큰의 개수가 하나 줄어든다.

  3. 따라서 위 반복문은 결과적으로 두 번 밖에 돌지 않게 된다.



위 코드에서 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문을 나오게 된다.



countTokens를 쓰는 방법 대신 while + hasMoreTokens를 사용할 수 있다. 결과에 유의미한 차이는 없다.




- 다른 사람 풀이

https://velog.io/@cjhlsb/Algorithm-%EB%B0%B1%EC%A4%80-2480%EB%B2%88-%EC%A3%BC%EC%82%AC%EC%9C%84-%EC%84%B8%EA%B0%9C

이 분은 다섯가지 분기가 아닌 네가지 분기를 만들었다. a == ba == c는 a를 공통으로 갖고 있기 때문에 묶어준 듯 하다. b == c만 따로 처리해주었고, 자바의 max 메소드를 활용하여 최댓값을 구했다.


확실히 내 코드와 비교하면 코드가 깔끔해 보인다. 하지만 a == b, a == c, b == c 이 조건의 의미를 잘 모르겠다. a와 b가 같고, a와 c가 같으면 b와 c도 같기 때문에 하나의 조건은 필요 없어 보인다



사실 백준 문제를 몇 개 안 풀어봤지만, 백준에서 측정해주는 결과는 별로 신뢰가 가지 않는다. 똑같은 코드를 여러번 제출했을 때, 서로 다른 결과를 얻은 적이 많기 때문이다. 따라서 어떤 코드가 빠르고, 효율이 좋은지 측정하기에 적절하지 않다는 생각이 들었다. 그리고 데이터 양이 적을 경우 A풀이가 B풀이 보다 빠르지만, 데이터 양이 많아지면 B풀이가 A풀이 보다 빠를 경우가 존재한다는 생각이 들었다.


따라서 결과 측정과 성능 테스트를 위해 CS, 알고리즘, 자료구조에 대한 지식이 필요하다고 느꼈다.



[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-else if-else를 
대신하는 것은 어떨까?

결론부터 말하자면 그럴 수 없다. 더 정확히 말하면 대체 할 수
있지만 매우 비효율 적이다. 예를 들어, 100개의 조건을 
작성할 때, if문 100개를 사용하면 100번의 검사가 필수적으로 
이루어진다. 하지만 if-else if-else를 사용한다면 해당 조건을
찾으면 나머지 조건은 검사하지 않는다. 
profile
hi

0개의 댓글