[백준] 1546 : 평균 - JAVA

Benjamin·2022년 11월 6일
0

BAEKJOON

목록 보기
9/70

슈도코드

solution() {
float answer = 0
공백을 기준으로 나누어 String[] scoreStrArray에 각각 값을 넣기
String[] scoreStrArray을 int[] scoreIntArray에 그대로 담기
scoreIntArray의 최대값 구해 int변수 max에 담기
int sum 선언
for(scoreIntArray의 크기만큼 반복) {
	if(각 인덱스의 값 != max) 각 인덱스의 값 = 각 인덱스의 값/max*100
    sum += 각 인덱스의 값
}
answer = String.format("%.3f", (sum / N))

return answer
}

main() {
int형 변수 N을 입력받음
String형 변수 scores를 입력받음
solution()호출해 리턴값 출력
}

Troubleshooting

import java.util.Arrays;
import java.util.Scanner;

public class Main {
	public static String solution(int N, String scores) {
		String answer;
		int sum = 0;
		int[] scoreIntArray = new int[N];
		
		String[] scoreStrArray =scores.split(" ");
		
		for(int index=0; index < N; index ++) {
			scoreIntArray[index] = Integer.parseInt(scoreStrArray[index]);
		}
		
		Arrays.sort(scoreIntArray);
		int max = scoreIntArray[N-1];
		
		for(int index=0; index < N; index ++) {
			int score = scoreIntArray[index];
			int newScore = score/max*100; // 논리 오류 발생!!!
			scoreIntArray[index] = newScore;
			sum += scoreIntArray[index];
		}
		float result = sum/N;
		answer = String.format("%.3f", result);
		return answer;
	}

	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		
		int N = scanner.nextInt();
		String trashValue = scanner.nextLine();
		String scores = scanner.nextLine();
		scanner.close();
		
		System.out.println(solution(N, scores));
	}
}

문제

결과가 예제와 다르게 나와서 디버깅해보니, newScore에 0이 들어가서, 최대값을 제외한 나머지값들이 0으로 바뀌는현상을 발견했다.

원인

  1. score, max가 int형이고, max가 무조건 크거나 같으므로 1.0 혹은 0.xxx가 결과일것이다. 근데 int끼리 나누면 소수점이 다 생략되므로, 0에 아무리 100을 곱해도 결과가 0이되는것이었다.
  2. 계산한 결과(newScore)가 int이면 중요한 소수점이 생략된다.
  3. 새로 구한 점수를 더한 sum변수도 int형이라 더하고나서 소수점이 다 생략된다.

해결

  1. 나누는 변수를 나누기 전부터 float로 형변환하여 계산해야한다. 그래야 소수점이 살아있다!
    (float)score / (float)max * 100.0f
  2. int newScore -> float newScore 로 변경
  3. int sum -> float sum 으로 변경

제출코드

import java.util.Arrays;
import java.util.Scanner;

public class Main {
	public static String solution(int N, String scores) {
		String answer;
		float sum = 0.0f;
		int[] scoreIntArray = new int[N];
		
		String[] scoreStrArray =scores.split(" ");
		
		for(int index=0; index < N; index ++) {
			scoreIntArray[index] = Integer.parseInt(scoreStrArray[index]);
		}
		
		Arrays.sort(scoreIntArray);
		int max = scoreIntArray[N-1];
		
		for(int index=0; index < N; index ++) {
			int score = scoreIntArray[index];
			float newScore = (float)score / (float)max * 100.0f;
			sum += newScore;
		}
		float result = sum/N;
		answer = String.format("%.3f", result);
		return answer;
	}

	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		
		int N = scanner.nextInt();
		String trashValue = scanner.nextLine();
		String scores = scanner.nextLine();
		scanner.close();
		
		System.out.println(solution(N, scores));
	}
}

공부한 항목

  • 나눗셈 소수점 표현 : String.format("%.3f", answer) 사용
  • float와 double 차이 : folat(4byte) double(8byte) && float는 선언시 숫자뒤에'f'써야함
  • 구분자로 문자 자르기 : 문자열.split("기준 문자") -> String[]로 반환함
  • int 배열의 최대값, 최소값 구하기 : Arrays.sort(배열명) -> 오름차순으로 정렬되므로 index가 0인 값은 최소값, index가 length-1인 값은 최대값이다.

다른풀이

코드

public class Main {
	public static float solution(int N, int[] scores) {
		float answer;
		int sum = 0;
		Arrays.sort(scores);
		int max = scores[N-1];
		for(int index=0; index < N; index ++) {
			sum += scores[index];
		}
		answer = sum * 100.0f / max / N;
		return answer;
	}

	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		
		int N = scanner.nextInt();
		int[] scores = new int[N];
		for(int i =0; i<N; i++) {
			scores[i] = scanner.nextInt();
		}
		scanner.close();
		
		System.out.println(solution(N, scores));
	}
}

내 코드와 차이점

  • 🖍한줄에 공백으로 구분된 int를 받을 때, for문을 이용해서 차례로 배열에 넣을 수 있다.
  • 🖍int형이 연산에서 float형과 연산시 int는 표현범위가 더 큰 float로 자동 형변환 된다.
  • 수학적으로 더 간단한 로직이 있으면, 그것을 사용한다.(개별로 연산하나, 합을 구한 후 연산하나 동일함)
  • 수학적으로는 곱셈을 먼저하든 나눗셈을 먼저하든 결과가 동일한것이더라도, 코드에서는 피연산자의 타입에 따라 결과가 달라질 수 있다.
    따라서 의도와 타입에따라 연산순서를 바꾸어서 해결할 수 있다면 그렇게해도된다.

0개의 댓글