Computer >> 컴퓨터 >  >> 프로그래밍 >> C++

C++에서 배열의 평균 구하기: 반복문과 재귀 방식 완벽 가이드

N개의 정수로 이루어진 배열 arr[N]이 주어졌을 때, 그 배열의 평균값을 구하는 것이 과제입니다. 평균을 구하는 방법은 크게 반복(iterative) 방식과 재귀(recursive) 방식 두 가지가 있으며, 이 글에서는 두 방법을 모두 예제 코드와 함께 자세히 설명합니다.

배열의 평균은 다음과 같이 정의할 수 있습니다.

배열의 평균 = 배열의 모든 요소의 합 ÷ 요소의 총개수

방법 1. 반복문(Iterative)을 이용한 평균 계산

반복 방식은 조건이 참(true)인 동안 명령문을 계속 실행하는 for 루프, while 루프, do-while 루프 같은 반복문을 활용하는 기법입니다.

먼저 입력·출력 예제를 살펴본 뒤, 반복문으로 어떻게 구현하는지 단계별로 알아보겠습니다.

입력 · 출력 예제

입력

arr[] = {1, 2, 4, 5, 8}

출력

4

설명

모든 요소의 합 = 1 + 2 + 4 + 5 + 8 = 20
요소의 총개수 = 5
평균 = 20 / 5 = 4

입력

arr[] = {10, 20, 30, 40}

출력

25

해결 접근 방식 (반복)

  • 루프를 사용해 배열의 각 요소를 하나씩 순회합니다.

  • 배열의 끝에 도달할 때까지 각 요소를 계속 더해 합계를 구합니다.

  • 합계를 요소의 총개수로 나누어 평균을 반환합니다.

알고리즘

시작
Step 1→ 반복 방식으로 평균을 계산하는 함수 선언
    double avg(int arr[], int size)
        int sum = 0 선언
        Loop For int i=0 and i<size and i++
            sum += arr[i]
        End
        return sum/size
Step 2→ main() 함수에서
    int arr[] = {2,3,1,6,8,10} 선언
    int size = sizeof(arr)/sizeof(arr[0]) 선언
    avg(arr, size) 호출
종료

예제 코드

#include <iostream>
using namespace std;

// 반복 방식으로 평균을 계산하는 함수
double avg(int arr[], int size){
    int sum = 0;
    for (int i = 0; i < size; i++)
        sum += arr[i];
    return sum / size;
}

int main(){
    int arr[] = {2, 3, 1, 6, 8, 10};
    int size = sizeof(arr) / sizeof(arr[0]);
    cout << "반복 방식으로 구한 배열의 평균 : " << avg(arr, size) << endl;
    return 0;
}

실행 결과

위 코드를 실행하면 다음과 같은 결과가 출력됩니다.

반복 방식으로 구한 배열의 평균 : 5

방법 2. 재귀(Recursive)를 이용한 평균 계산

그렇다면 재귀 방식이란 무엇일까요? 재귀 방식은 원하는 결과를 얻을 때까지 함수를 스스로 반복해서 호출하는 기법입니다. 재귀 호출에서는 함수가 반환하는 값들이 스택(stack) 메모리에 저장된다는 특징이 있습니다.

입력 · 출력 예제

입력

arr[] = {2, 4, 6, 8}

출력

5

설명

모든 요소의 합 = 2 + 4 + 6 + 8 = 20
요소의 총개수 = 4
평균 = 20 / 4 = 5

입력

arr[] = {12, 23, 45, 15}

출력

19

해결 접근 방식 (재귀)

  • 배열의 끝에 도달할 때까지 함수를 계속해서 재귀 호출합니다.

  • 호출 과정에서 배열의 모든 요소를 더하고, 배열의 끝에 도달하면 최종적으로 평균을 반환합니다.

알고리즘

시작
Step 1→ 재귀 방식으로 평균을 계산하는 함수 선언
    double recursive(int arr[], int i, int size)
        IF (i == size-1)
            return arr[i]
        End
        IF (i == 0)
            return ((arr[i] + recursive(arr, i+1, size)) / size)
        End
        return (arr[i] + recursive(arr, i+1, size))
Step 2→ double avg(int arr[], int size)
    return recursive(arr, 0, size)
Step 3→ main() 함수에서
    int arr[] = {1,5,3,2,6,7} 선언
    int size = sizeof(arr)/sizeof(arr[0]) 선언
    average(arr, size) 호출
종료

예제 코드

#include <iostream>
using namespace std;

// 재귀적으로 평균을 계산하는 함수
double recursive(int arr[], int i, int size){
    if (i == size - 1)
        return arr[i];
    if (i == 0)
        return ((arr[i] + recursive(arr, i + 1, size)) / size);
    return (arr[i] + recursive(arr, i + 1, size));
}

// 평균을 반환하는 함수
double average(int arr[], int size){
    return recursive(arr, 0, size);
}

int main(){
    int arr[] = {1, 5, 3, 2, 6, 7};
    int size = sizeof(arr) / sizeof(arr[0]);
    cout << "재귀 방식으로 구한 배열의 평균 : " << average(arr, size) << endl;
    return 0;
}

실행 결과

위 코드를 실행하면 다음과 같은 결과가 출력됩니다.

재귀 방식으로 구한 배열의 평균 : 4

마무리 및 참고 사항

두 방식 모두 시간 복잡도는 O(N)으로 동일하지만, 반복 방식은 추가 메모리를 거의 사용하지 않는 반면, 재귀 방식은 호출할 때마다 스택 메모리를 사용하기 때문에 배열의 크기가 매우 클 경우 스택 오버플로우(stack overflow)가 발생할 수 있습니다. 따라서 일반적인 상황에서는 반복 방식이 더 안정적이고 효율적입니다.

또한 위 예제에서 sum과 size가 모두 int형이므로 나눗셈이 정수 나눗셈으로 처리되어 소수점 이하는 버려집니다. 보다 정확한 평균값이 필요하다면 (double)sum / size처럼 형 변환(casting)을 활용하는 것이 좋습니다.