안녕하세요.
오늘은 백준 2108번 '통계학' 문제풀이를 해보겠습니다
이번 통계학 문제는 숫자 N과 N만큼의 숫자들에 대한 산술평균, 중앙값, 최빈값, 범위값을 구하는 총 4파트로 이루어져있습니다.
입력예시
5 // 숫자 N
1
3
8
-2
2
출력예시
2
2
1
10
그럼 바로 문제풀이를 해보겠습니다.
우선 숫자 N을 받아오고 N만큼의 숫자들도 받아와 리스트에 저장합니다.
int n = int.Parse(Console.ReadLine()!);
List<int> numbers = new List<int>();
// N번 반복하여 숫자들을 입력받아 리스트에 추가
for (int i = 0; i < n; i++)
{
numbers.Add(int.Parse(Console.ReadLine()!));
}
첫번째로 산술평균을 계산해보겠습니다.
값들의 평균을 구해주고 그 평균값에 대한 반올림을 진행합니다. 그리고 int로 강제형식변환을 해주면 정수로 변환됩니다.
산술평균을 출력해줍니다.
double average = numbers.Average();
int meanResult = (int)Math.Round(average);
Console.WriteLine(meanResult);
두번째로 중앙값을 계산해보겠습니다.
숫자들의 리스트를 정렬해주고, 리스트의 중간값 인덱스를 구해줍니다. n은 항상 홀수로 주어지기 때문에 잘못된 중앙값을 참조하지 않습니다.
중앙값을 출력해줍니다.
numbers.Sort();
int medianIndex = (numbers.Count - 1) / 2;
int medianResult = numbers[medianIndex];
Console.WriteLine(medianResult);
세번째로 최빈값을 계산해보겠습니다.
최빈값은 LINQ로 계산해야하는데 저는 LINQ에 미숙해서 이번 문제를 풀면서 가장 공부를 많이 해야했던 파트였습니다.
우선 숫자들에 GroupBy를 적용시켜줍니다.
GroupBy는 원본 리스트에서 3이라는 키를 가진 하나의 IGrouping<int, int>객체를 반환합니다. 예를들어볼 때 이 IGrouping객체는 Key로 숫자 3을 가지며, 내부적으로 {3, 3, 3}이라는 요소 컬렉션을 담고 있습니다.
Select는 IGrouping컬렉션을 받아서 Number와 Count 속성을 가진 새로운 익명 형식 객체를 만들고, 이 객체들의 컬렉션인 IEnumerable<T>을 반환합니다. 이 과정을 통해 데이터가 평탄화되어 정렬하기 쉬운 구조로 바뀝니다.
정렬을 해주고, List로 변환합니다.
Count가 같은 값이 여러 개 있을 때는 최빈값 중 두 번째로 작은 값을 출력해줍니다.
var frequencyList = numbers
.GroupBy(x => x)
.Select(g => new { Number = g.Key, Count = g.Count() })
.OrderByDescending(g => g.Count)
.ThenBy(g => g.Number)
.ToList();
int modeResult;
if (frequencyList.Count > 1 && frequencyList[0].Count == frequencyList[1].Count)
{
modeResult = frequencyList[1].Number;
}
else
{
modeResult = frequencyList[0].Number;
}
Console.WriteLine(modeResult);
마지막으로 범위계산을 해보겠습니다.
간단하게 가장 큰 수, 작은 수를 더하여 빼줍니다.
범위값을 출력합니다.
int max = numbers.Max();
int min = numbers.Min();
int rangeResult = max - min;
Console.WriteLine(rangeResult);
이번 문제를 풀면서 LINQ를 손에 익도록 연습해야겠다는걸 깨닫게 되었습니다.
다음은 전체코드입니다.
감사합니다.
internal class Program
{
static void Main(string[] args)
{
int n = int.Parse(Console.ReadLine()!);
List<int> numbers = new List<int>();
// N번 반복하여 숫자들을 입력받아 리스트에 추가
for (int i = 0; i < n; i++)
{
numbers.Add(int.Parse(Console.ReadLine()!));
}
//산술평균
double average = numbers.Average();
int meanResult = (int)Math.Round(average); // c#의 기본 반올림은 '은행반올림' 이다. 근데 반올림 한 수가 0.5일때 0에서 더 먼 쪽으로 반올림 하는것이 MidpointRounding.AwayFromZero이다.
Console.WriteLine(meanResult);
//중앙값 계산
numbers.Sort();
int medianIndex = (numbers.Count - 1) / 2;
int medianResult = numbers[medianIndex];
Console.WriteLine(medianResult);
//최빈값 계산
var frequencyList = numbers
.GroupBy(x => x)
.Select(g => new { Number = g.Key, Count = g.Count() })
.OrderByDescending(g => g.Count)
.ThenBy(g => g.Number)
.ToList();
int modeResult;
if (frequencyList.Count > 1 && frequencyList[0].Count == frequencyList[1].Count)
{
modeResult = frequencyList[1].Number;
}
else
{
modeResult = frequencyList[0].Number;
}
Console.WriteLine(modeResult);
//범위계산
int max = numbers.Max();
int min = numbers.Min();
int rangeResult = max - min;
Console.WriteLine(rangeResult);
}
}
'알고리즘 풀이' 카테고리의 다른 글
| [C#] 백준 2775번 문제풀이 (0) | 2025.12.26 |
|---|---|
| [C#] 백준 28702번 문제풀이 (0) | 2025.10.19 |
| [C#] 백준 1874번 풀이 (0) | 2025.10.16 |
| [C#] 백준 1966번 문제풀이 (0) | 2025.10.12 |
| [C#] 백준 1764번 문제풀이 (2) | 2025.08.13 |