이 글에서는 비교 연산을 최소한으로 사용하여 주어진 세 값의 중간값(middle value)을 찾는 방법을 알아봅니다. 예를 들어 세 개의 숫자 (10, 30, 20)이 주어졌다면, 가운데 값인 20을 반환해야 합니다. 정렬 없이 조건문만으로 해결할 수 있으며, 최대 2번의 비교만으로 중간값을 구할 수 있다는 점이 이 방법의 핵심입니다.
먼저 알고리즘의 흐름을 살펴본 뒤, 이를 C++ 코드로 직접 구현해 보겠습니다.
알고리즘
세 수 a, b, c가 주어졌을 때, 다음 의사코드(pseudocode)와 같은 논리로 중간값을 찾습니다.
middle_of_three(a, b, c):
입력: 세 개의 숫자 a, b, c
출력: 세 수 중 가운데 값
시작
만약 a > b 라면
만약 b > c 라면
b 반환 // a > b > c 이므로 b가 중간값
아니고 a > c 라면
c 반환 // c < a < b 이므로 c가 중간값
아니면
a 반환 // c >= a > b 이므로 a가 중간값
아니면 (a <= b)
만약 a > c 라면
a 반환 // b > a > c 이므로 a가 중간값
아니고 b > c 라면
c 반환 // a <= c < b 이므로 c가 중간값
아니면
b 반환 // a <= b <= c 이므로 b가 중간값
종료이 알고리즘은 어떤 경우에도 비교를 최대 2번만 수행하므로, 단순히 세 수를 정렬하는 방식(보통 3번 이상의 비교 필요)보다 효율적입니다.
C++ 구현 예제
위 알고리즘을 그대로 C++ 함수로 옮기면 다음과 같습니다.
#include <iostream>
using namespace std;
int mid_three(int a, int b, int c) {
if (a > b) {
if (b > c)
return b;
else if (a > c)
return c;
else
return a;
} else {
if (a > c)
return a;
else if (b > c)
return c;
else
return b;
}
}
int main() {
int a = 10, b = 30, c = 20;
cout << "Middle Out of Three " << mid_three(a, b, c);
}동작 원리
먼저 a와 b를 한 번 비교하여 어느 쪽이 큰지 판별합니다. 이후 두 번째 비교를 통해 나머지 값 c와의 대소 관계를 확인하면, 세 수의 상대적인 순서가 특정되어 중간값을 바로 반환할 수 있습니다. 각 분기마다 이미 확정된 두 수의 관계를 활용하기 때문에 추가 비교 없이도 정확한 답을 얻을 수 있습니다.
실행 결과
위 코드를 컴파일하여 실행하면 다음과 같은 출력을 얻습니다.
Middle Out of Three 20
입력값 (10, 30, 20)에서 가장 작은 값은 10, 가장 큰 값은 30이므로, 남은 값인 20이 중간값으로 올바르게 출력됩니다. 이 방법은 세 개 이상의 값을 다루는 통계 계산, 클램핑(clamping), 메디안 필터 등 다양한 상황에서 응용할 수 있습니다.