using System;
/*
delegate 왜, 언제 사용?
'값'이 아닌 '코드' 자체를 매개변수에 넘기고 싶을 때 사용.
*/
// 델리게이트를 사용하여 버블 정렬 알고리즘을 구현하고, 오름차순과 내림차순으로 정렬하는 방법
// Comparer 델리게이트를 통해 정렬 방식을 동적으로 변경할 수 있다
namespace UsingCallback
{
delegate int Compare(int a, int b); // Compare라는 이름의 델리게이트를 선언합니다.
// 이 델리게이트는 두 개의 정수를 매개변수로 받아
// 정수 값을 반환하는 메서드를 참조할 수 있습니다.
class MainApp
{
static int AscendCompare(int a, int b) // AscendCompare():
// Compare 대리자가 참조할 비교 메서드.
// 두 개의 정수 a와 b를 비교하여,
// a가 b보다 크면 1, 같으면 0, 작으면 -1을 반환합니다.
// 오름차순 정렬을 위한 비교 메서드입니다.
{
if (a > b)
return 1;
else if (a == b)
return 0;
else
return -1;
}
static int DescendCompare(int a, int b) // DescendCompare():
// Compare 대리자가 참조할 비교 메서드.
// 내림차순 정렬을 위한 비교 메서드입니다.
{
if (a < b)
return 1;
else if (a == b)
return 0;
else
return -1;
}
// Comparer 델리게이트를 통해 정렬 방식을 동적으로 변경할 수 있다.
static void BubbleSort(int[] DataSet, Compare Comparer) // BubbleSort(): 정렬을 위한 메서드
// 정수형 배열 타입의 DataSet과,
// Compare 델리게이트 타입의 Comparer를
// 매개변수로 받아,
// 버블 정렬 알고리즘을 사용하여 DataSet 배열을 정렬합니다.
// Comparer 델리게이트를 사용하여 두 요소를 비교합니다.
// Comparer(DataSet[j], DataSet[j + 1]) > 0이면
// 두 요소의 순서를 바꿉니다.
{
int i = 0; // i: 바깥쪽 반복문 카운터 변수
int j = 0; // j: 안쪽 반복문의 카운터 변수
int temp = 0; // temp: 두 요소의 값을 교환할 때 사용되는 임시 변수
for (i = 0; i < DataSet.Length - 1; i++) // 배열의 크기 - 1만큼 반복합니다.
{
for (j = 0; j < DataSet.Length - (i + 1); j++) // 배열의 크기 - (i + 1)만큼 반복합니다.
// i가 증가할수록 안쪽 반복문의 횟수가 줄어들게 했는데,
// 바깥쪽 반복문을 한 번 돌 때마다
// 가장 큰 값이 배열의 마지막으로 이동하기 때문임.
{
if (Comparer(DataSet[j], DataSet[j + 1]) > 0) // Comparer 델리게이트를 사용하여
// DataSet[j]와 DataSet[j + 1] 요소를 비교합니다.
// Comparer는 AscendCompare() 또는 DescendCompare() 메서드를 참조하며,
// 이 메서드들은 두 요소를 비교하여 순서를 판별합니다.
// 만약 Comparer의 반환 값이 0보다 크면,
// 즉 두 요소의 순서가 잘못되었으면
// temp 변수를 사용하여 두 요소의 값을 교환합니다.
{
temp = DataSet[j + 1];
DataSet[j + 1] = DataSet[j];
DataSet[j] = temp;
}
}
}
}
static void Main(string[] args)
{
int[] array = { 3, 7, 4, 2, 10 }; // 정수형 배열 array를 선언하고 초기화합니다.
Console.WriteLine("Sorting ascending...");
BubbleSort(array, new Compare(AscendCompare)); // BubbleSort 메서드를 호출하여
// array 배열을 오름차순으로 정렬합니다.
// new Compare(AscendCompare):
// 'AscendCompare ()메서드를 참조'하는 Compare 델리게이트를 생성합니다.
//
// BubbleSort 메서드를 호출할 때,
// array 배열과, AscendCompare 메서드를 참조하는 Compare 델리게이트를 전달합니다.
for (int i = 0; i < array.Length; i++) // for 문을 사용하여 정렬된 array 배열을 출력합니다.
Console.Write($"{array[i]} ");
int[] array2 = { 7, 2, 8, 10, 11 }; // 정수형 배열 array2를 선언하고 초기화합니다.
Console.WriteLine("\nSorting descending...");
BubbleSort(array2, new Compare(DescendCompare)); // BubbleSort 메서드를 호출하여
// array2 배열을 내림차순으로 정렬합니다.
// new Compare(DescendCompare):
// 'DescendCompare() 메서드를 참조'하는 Compare 델리게이트를 생성합니다.
for (int i = 0; i < array2.Length; i++) // for 문을 사용하여 정렬된 array2 배열을 출력합니다.
Console.Write($"{array2[i]} ");
Console.WriteLine();
}
}
}
/*
출력 결과
Sorting ascending...
2 3 4 7 10
Sorting descending...
11 10 8 7 2
*/
코드 설명
이 C# 코드는 델리게이트를 사용하여 버블 정렬 알고리즘을 구현하고, 오름차순과 내림차순으로 정렬하는 방법을 보여주는 예제입니다.
Compare 델리게이트
delegate int Compare(int a, int b);
Compare라는 이름의 델리게이트를 선언합니다. 이 델리게이트는 두 개의 정수를 매개변수로 받아 정수 값을 반환하는 메서드를 참조할 수 있습니다.AscendCompare 메서드
static int AscendCompare(int a, int b)
{
if (a > b)
return 1;
else if (a == b)
return 0;
else
return -1;
}
a와 b를 비교하여 a가 b보다 크면 1, 같으면 0, 작으면 -1을 반환합니다. 이 메서드는 오름차순 정렬을 위한 비교 함수입니다.DescendCompare 메서드
static int DescendCompare(int a, int b)
{
if (a < b)
return 1;
else if (a == b)
return 0;
else
return -1;
}
a와 b를 비교하여 a가 b보다 작으면 1, 같으면 0, 크면 -1을 반환합니다. 이 메서드는 내림차순 정렬을 위한 비교 함수입니다.BubbleSort 메서드
static void BubbleSort(int[] DataSet, Compare Comparer)
{
int i = 0;
int j = 0;
int temp = 0;
for (i = 0; i < DataSet.Length - 1; i++)
{
for (j = 0; j < DataSet.Length - (i + 1); j++)
{
if (Comparer(DataSet[j], DataSet[j + 1]) > 0)
{
temp = DataSet[j + 1];
DataSet[j + 1] = DataSet[j];
DataSet[j] = temp;
}
}
}
}
DataSet과 Compare 델리게이트 Comparer를 매개변수로 받습니다.DataSet 배열을 정렬합니다.Comparer 델리게이트를 사용하여 두 요소를 비교합니다. Comparer(DataSet[j], DataSet[j + 1]) > 0이면 두 요소의 순서를 바꿉니다.Main 메서드
int[] array = { 3, 7, 4, 2, 10 };
Console.WriteLine("Sorting ascending...");
BubbleSort(array, new Compare(AscendCompare)); // 오름차순 정렬
for (int i = 0; i < array.Length; i++)
Console.Write($"{array[i]} ");
int[] array2 = { 7, 2, 8, 10, 11 };
Console.WriteLine("\nSorting descending...");
BubbleSort(array2, new Compare(DescendCompare)); // 내림차순 정렬
for (int i = 0; i < array2.Length; i++)
Console.Write($"{array2[i]} ");
Console.WriteLine();
int[] array = { 3, 7, 4, 2, 10 };: 정수형 배열 array를 선언하고 초기화합니다.BubbleSort(array, new Compare(AscendCompare));: BubbleSort 메서드를 호출하여 array 배열을 오름차순으로 정렬합니다. new Compare(AscendCompare)는 AscendCompare 메서드를 참조하는 Compare 델리게이트를 생성합니다.for 문을 사용하여 정렬된 array 배열을 출력합니다.int[] array2 = { 7, 2, 8, 10, 11 };: 정수형 배열 array2를 선언하고 초기화합니다.BubbleSort(array2, new Compare(DescendCompare));: BubbleSort 메서드를 호출하여 array2 배열을 내림차순으로 정렬합니다. new Compare(DescendCompare)는 DescendCompare 메서드를 참조하는 Compare 델리게이트를 생성합니다.for 문을 사용하여 정렬된 array2 배열을 출력합니다.출력 결과
Sorting ascending...
2 3 4 7 10
Sorting descending...
11 10 8 7 2
BubbleSort메서드
BubbleSort 메서드가 배열 { 3, 7, 4, 2, 10 } 을 정렬하는 과정을 단계별로 보여줄게.
1. BubbleSort 메서드 호출
int[] array = { 3, 7, 4, 2, 10 };
Console.WriteLine("Sorting ascending...");
BubbleSort(array, new Compare(AscendCompare)); // 오름차순 정렬
BubbleSort 메서드를 호출할 때 array 배열과 AscendCompare 메서드를 참조하는 Compare 델리게이트를 전달합니다.
2. BubbleSort 메서드 내부
static void BubbleSort(int[] DataSet, Compare Comparer)
{
int i = 0;
int j = 0;
int temp = 0;
for (i = 0; i < DataSet.Length - 1; i++)
{
for (j = 0; j < DataSet.Length - (i + 1); j++)
{
if (Comparer(DataSet[j], DataSet[j + 1]) > 0)
{
temp = DataSet[j + 1];
DataSet[j + 1] = DataSet[j];
DataSet[j] = temp;
}
}
}
}
DataSet에는 { 3, 7, 4, 2, 10 } 배열이, Comparer에는 AscendCompare 메서드가 전달됩니다.3. 버블 정렬 1회 실행
i = 0일 때, 안쪽 반복문은 j를 0부터 3까지 증가시키면서 다음과 같은 비교를 수행합니다.
j = 0: Comparer(DataSet[0], DataSet[1]) -> AscendCompare(3, 7) -> -1 (3 < 7)j = 1: Comparer(DataSet[1], DataSet[2]) -> AscendCompare(7, 4) -> 1 (7 > 4) -> 교환 { 3, 4, 7, 2, 10 }j = 2: Comparer(DataSet[2], DataSet[3]) -> AscendCompare(7, 2) -> 1 (7 > 2) -> 교환 { 3, 4, 2, 7, 10 }j = 3: Comparer(DataSet[3], DataSet[4]) -> AscendCompare(7, 10) -> -1 (7 < 10)1회 실행 후 배열은 { 3, 4, 2, 7, 10 } 이 됩니다.
4. 버블 정렬 2회 실행
i = 1일 때, 안쪽 반복문은 j를 0부터 2까지 증가시키면서 다음과 같은 비교를 수행합니다.
j = 0: Comparer(DataSet[0], DataSet[1]) -> AscendCompare(3, 4) -> -1 (3 < 4)j = 1: Comparer(DataSet[1], DataSet[2]) -> AscendCompare(4, 2) -> 1 (4 > 2) -> 교환 { 3, 2, 4, 7, 10 }j = 2: Comparer(DataSet[2], DataSet[3]) -> AscendCompare(4, 7) -> -1 (4 < 7)2회 실행 후 배열은 { 3, 2, 4, 7, 10 } 이 됩니다.
5. 버블 정렬 3회 실행
i = 2일 때, 안쪽 반복문은 j를 0부터 1까지 증가시키면서 다음과 같은 비교를 수행합니다.
j = 0: Comparer(DataSet[0], DataSet[1]) -> AscendCompare(3, 2) -> 1 (3 > 2) -> 교환 { 2, 3, 4, 7, 10 }j = 1: Comparer(DataSet[1], DataSet[2]) -> AscendCompare(3, 4) -> -1 (3 < 4)3회 실행 후 배열은 { 2, 3, 4, 7, 10 } 이 됩니다.
6. 버블 정렬 4회 실행
i = 3일 때, 안쪽 반복문은 j를 0으로 하여 다음과 같은 비교를 수행합니다.
j = 0: Comparer(DataSet[0], DataSet[1]) -> AscendCompare(2, 3) -> -1 (2 < 3)4회 실행 후 배열은 { 2, 3, 4, 7, 10 } 이 됩니다.
Comparer(DataSet[j], DataSet[j + 1]) > 0 부분 설명
Comparer(DataSet[j], DataSet[j + 1])는 Compare 델리게이트를 통해 DataSet[j]와 DataSet[j + 1] 요소를 비교하는 코드입니다.
Compare 델리게이트는 AscendCompare 메서드를 참조하고 있으므로, AscendCompare(DataSet[j], DataSet[j + 1])를 호출하는 것과 같습니다.
AscendCompare 메서드는 두 요소를 비교하여, 첫 번째 요소가 두 번째 요소보다 크면 1, 같으면 0, 작으면 -1을 반환합니다.
따라서 Comparer(DataSet[j], DataSet[j + 1]) > 0는 DataSet[j]가 DataSet[j + 1]보다 큰 경우 true를 반환하고, 그렇지 않으면 false를 반환합니다. 즉, 두 요소의 순서가 잘못되었는지 판별하는 조건입니다.