날짜(Date)는 일, 월, 연도로 구성된 숫자이며, 다양한 형식으로 표현할 수 있습니다.
이번 글에서는 선택 정렬(Selection Sort)을 사용하여 날짜를 정렬하는 C++ 프로그램을 살펴보겠습니다. 먼저 이 개념에 필요한 핵심 요소들을 하나씩 알아보겠습니다.
날짜 정렬의 기본 개념
날짜를 정렬하려면 날짜 구조와 유효성 검사에 대한 명확한 이해가 필요합니다. 정렬 기법을 적용하기 전에, 사용자가 입력한 날짜가 실제로 존재하는 유효한 날짜인지 먼저 확인해야 합니다. 예를 들어 2월 29일은 윤년에만 존재하는 날짜입니다.
유효성 검사가 끝나면 본격적으로 정렬을 수행합니다. 정렬은 우선순위에 따라 단계적으로 진행됩니다. 먼저 연도를 기준으로 정렬하고, 연도가 같으면 월을 기준으로, 월까지 같으면 일을 기준으로 오름차순 정렬합니다.
선택 정렬(Selection Sort)이란?
선택 정렬은 배열에서 최솟값을 찾아 맨 앞으로 배치한 뒤, 정렬이 완료된 부분을 제외한 나머지 배열에서 같은 작업을 반복하는 정렬 알고리즘입니다. 이 과정을 거치면 각 요소가 오름차순으로 자기 위치에 배치됩니다.
이 프로그램은 선택 정렬 기법을 활용해 사용자가 입력한 여러 날짜를 정렬합니다.
정렬되지 않은 상태의 3개 날짜를 예로 들어 보겠습니다.
입력 : 4 1 2012 31 5 2019 19 12 2012 출력 : 4 1 2012 19 12 2012 31 5 2019
결과 설명
세 날짜 모두 유효한 날짜이므로, 프로그램은 이를 연도 → 월 → 일 순서의 우선순위로 비교하여 오름차순으로 정렬합니다. 2012년 두 날짜는 월(1월, 12월)을 기준으로 정렬되고, 2019년 날짜가 가장 뒤에 배치됩니다.
전체 예제 코드
#include<iostream>
using namespace std;
struct date{
int day;
int month;
int year;
int valid = 1;
};
int datevalidate(int dd, int mm, int yy){
if(yy>=100 && yy<=9999){
if(mm>=1 && mm<=12){
if((dd>=1 && dd<=31) && (mm==1 || mm==3 || mm==5 || mm==7 || mm==8 || mm==10 || mm==12));
else if((dd>=1 && dd<=30) && (mm==4 || mm==6 || mm==9 || mm==11));
else if((dd>=1 && dd<=28) && (mm==2));
else if(dd==29 && mm==2 && (yy%400==0 ||(yy%4==0 && yy%100!=0)));
else
return 0;
} else{
return 0;
}
} else {
return 0;
}
}
int main(){
cout<<"Enter 5 dates to be sorted:\n";
struct date input[5];
for(int i=0; i<5; i++){
cout<<"Enter Date "<<(i+1)<<" : ";
cin>>input[i].day;
cin>>input[i].month;
cin>>input[i].year;
input[i].valid = datevalidate(input[i].day, input[i].month, input[i].year);
if(input[i].valid){
cout<<"Date is invalid";
exit(0);
}
}
for (int i=0; i<4; i++){
for (int j=i+1; j<5; j++){
if (input[i].year > input[j].year){
struct date temp = input[i];
input[i] = input[j];
input[j] = temp;
}
else if (input[i].year == input[j].year && input[i].month > input[j].month){
struct date temp = input[i];
input[i] = input[j];
input[j] = temp;
}
else if (input[i].year == input[j].year && input[i].month == input[j].month && input[i].day > input[j].day){
struct date temp = input[i];
input[i] = input[j];
input[j] = temp;
}
}
}
cout<<"Sorted dates are : \n";
for(int i=0; i<5; i++){
cout<<input[i].day<<" "<<input[i].month<<" "<<input[i].year;
cout<<endl;
}
}코드 동작 원리
1. 날짜 유효성 검사(datevalidate 함수)
- 연도는 100~9999 범위인지 확인합니다.
- 월은 1~12 사이인지 확인합니다.
- 31일까지 있는 달(1, 3, 5, 7, 8, 10, 12월), 30일까지 있는 달(4, 6, 9, 11월), 2월(28일)을 각각 구분하여 검사합니다.
- 2월 29일은 윤년 조건(400으로 나누어떨어지거나, 4로 나누어떨어지면서 100으로는 나누어떨어지지 않는 해)을 만족할 때만 유효합니다.
2. 선택 정렬 로직
- 바깥 루프와 안쪽 루프를 이중으로 돌며 날짜들을 서로 비교합니다.
- 연도가 크면 교환하고, 연도가 같으면 월을, 월도 같으면 일을 비교하여 교환합니다.
- 구조체 전체를 임시 변수(temp)로 교환하므로 day, month, year가 한 번에 이동합니다.
실행 결과
Enter 5 dates to be sorted: Enter date 1 : 5 12 2019 Enter date 2 : 1 2 2012 Enter date 3 : 11 6 2324 Enter date 4 : 29 2 2652 Enter date 5 : 16 5 2012 Sorted dates are : 1 2 2012 16 5 2012 5 12 2019 11 6 2324 29 2 2652
출력 결과를 보면 2012년 날짜들이 월과 일 순서대로 먼저 배치되고, 이후 연도가 커지는 순서대로 정렬된 것을 확인할 수 있습니다. 특히 29 2 2652처럼 윤년의 2월 29일도 올바르게 처리되는 것을 볼 수 있습니다.