delegate 사용하여 정렬

00·2024년 12월 25일

C#

목록 보기
75/149
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;
}
  • 두 개의 정수 ab를 비교하여 ab보다 크면 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;
}
  • 두 개의 정수 ab를 비교하여 ab보다 작으면 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;
            }
        }
    }
}
  • 정수형 배열 DataSetCompare 델리게이트 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]) > 0DataSet[j]DataSet[j + 1]보다 큰 경우 true를 반환하고, 그렇지 않으면 false를 반환합니다. 즉, 두 요소의 순서가 잘못되었는지 판별하는 조건입니다.

0개의 댓글