innn

배열과 리스트 (문제 002) (ArithmeticException 에러 뜻) 본문

코딩 테스트/코테 문제 풀이

배열과 리스트 (문제 002) (ArithmeticException 에러 뜻)

33삼 2022. 9. 25. 00:11

비교적 간단한 문제. 문제에 주어진 내용을 프로그래밍 해서 그 문제에 요구한 내용을 잘 이해하고 프로그래밍을 했느냐 를 본 문제다.

간단한 문제인데, ArithmeticException 에러의 뜻도 발견한 시간이었다. (이 에러의 뜻은 마지막 문단의 빨간줄만 보심 됩니다. 결론부터 말하자면, 특정 변수의 값이 0으로 초기화된 채 그대로  나누기 된 것입니다!)

 

문제 002. 평균 구하기

 

세준이는 기말고사를 망쳤다. 그래서 점수를 조작해 집에 가져가기로 결심했다. 일단 세준이는 자기 점수 중 최댓값을 골랐다. 그런 다음 최댓값을 M이라 할 때 모든 점수를 점수/M*100으로 고쳤다. 예를 들어 세준이의 최고점이 70점, 수학 점수가 50점이라면 수학 점수는 50/70*100이므로 71.43점이다. 세준이의 성적을 이 방법으로 계산했을 때 새로운 평균을 구하는 프로그램을 작성하시오.

 

입력
1번째 줄에 시험을 본 과목의 개수 N이 주어진다. 해당 값은 1,000보다 작거나 같다. 2번째 줄에 세준이의 현재 성적이 주어진다. 해당 값은 100보다 적거나 같은, 음이 아닌 정수이고, 적어도 1개의 값은 0보다 크다.
출력
1번째 줄에 새로운 평균을 출력한다. 실제 정답과 출력값의 절대 오차 또는 상대 오차가 10^-2 이하이면 정답이다. 

 

입력과 출력 예시

 

1단계 문제 분석하기

최고 점수를 기준으로 전체 점수를 다시 계산 해야한다. 따라서 모든 점수를 입력 받은 후에 최고점을 별도로 저장해야하는 것이다. (최고점만 그대로고, 나머지 점수들은 최고점에 의해서 변동되니까) 또한 문제에서 제시한 한 과목의 점수를 계산하는 식은 총합과 관련된 식으로 변환할 수 있다. 왜? 출력값총합에 의한 평균 점수 하나니까! 

따라서 일일이 변환 점수를 따로 구해서 다시 sum average할 필요 없이, 한번에 변환한 점수의 평균 점수를 구할 수 있는 것이다. 

 

변환 점수의 평균을 구하는 식(점수가 A B C 인 경우)

(A /M*100 + B/M*100 + C/M*100) / 3 = (A + B + C) * 100 / M / 3

 

2단계 손으로 풀어보기

1) 점수를 1차원 배열에 저장한다.

index   0   1   2   3    4  
점수    1 / 2 / 4 / 8 / 16

----------------------------------> 

 

2) 배열을 탐색하며 최고 점수와 점수의 총합을 구한다.

최고 점수 = 16, 총합 = 31

 

3) '총합 * 100 / 최고 점수 / 과목의 수'를 다시 계산해 다시 계산한 점수의 평균값을 출력한다.

총합 * 100 / 최고 점수 / 과목의 수 = 31 * 100 / 16 / 5 = 38.75

 

3단계 슈도코드 작성하기

변수 N에 과목의 수 입력받기
길이가 N인 1차원 배열 A[] 선언하기 
for(A[] 길이 만큼 반복하기) {
    A[i]에 각 점수 저장하기
}
for(A[] 길이만큼 반복하기) {
   최고점은 변수 max에, 총점은 변수 sum에 저장하기
}
sum * 100 / max / N 출력하기

 

4단계 코드 구현하기

코드를 구현한 식과 스스로 써본 해설을 각주로 달았다.

 

내가 처음 틀린 부분

두 가지 오류를 범했다. 

 

콘솔창에 뜬 에러는 아래와 같다. 

 

Exception in thread "main" java.lang.ArithmeticException: / by zero
at C.main(C.java:23)

 

오라클 java api 문서에서 java.lang.ArithmeticException 을 찾아보자 

 

https://docs.oracle.com/javase/8/docs/api/?java/lang/ArithmeticException.html 

 

Java Platform SE 8

 

docs.oracle.com

public class ArithmeticException extends RuntimeException
Thrown when an exceptional arithmetic condition has occurred. For example, an integer "divide by zero" throws an instance of this class.

예외적인 산술 조건이 발생했을 때 던져집니다. 예를 들어, "0으로 나누기"  정수는 이 클래스의 인스턴스를 표시합니다.

단순히 max와 sum을 int로 선언해서 발생한 일이었나? 싶었는데 보니까 19번 라인에서 max에 값을 초기화 시킬 때 왼쪽항과 오른쪽 항의 순서를 바꾼 것이 원인이었다. max 값에 그대로 0 이 저장된 상태로 포문을 나간 것. sNum[i]가 max보다 크다면 sNum[i]에 max(초기화 값0)를 저장한것이다..;; 어마무지한 실수였다. 

ArithmetiecException 이 0으로 나누었을 때 발생한 에러인 것을 알게된 시간이었다. 

 

** 아 물론 max와 sum을 선언할때도 long으로. 데이터 타입을 바꿔주어야 하기도 했다.

 

두개의 에러를 고치고 문제 2번도 클리어..