Лучшая подборка книг и информации по программированию.Скидка 11%, подарки к заказу и бесплатная доставка!
RSS иконка EMail иконка Домашняя иконка

  • Пример BubbleSorter.

    Написано 02.07.2010 21:26 devalmor Нет комментариев

    Теперь мы приведем пример, в котором делегаты чрезвычайно полезны. Напишем класс BubbleSorter. Он реализует статический метод Sort(), который в качестве первого параметра принимает массив объектов и сортирует его в возрастающем порядке. Например, если мы передадим массив int {0. 5, 6, 2,1}, метод отсортирует его так: {0,1. 2, 5, 6}.
    Алгоритм пузырьковой сортировки является довольно известным и очень простым (хотя неэффективным) способом сортировки чисел. Он работает, проходя по всему массиву, сравнивая каждую пару чисел и меняя их в случае необходимости, в результате чего большие числа постепенно перемещаются в конец массива. Для сортировки int метод пузырьковой сортировки выглядит так:

    // Это не часть примера
    for (int i=0; i for (int j=0; j if (j > i) // проблема с этой проверкой
    {
    int temp = sortArray [i]; // меняем i и j
    sort Array[i] = sortArray[j];
    sortArray[j] = temp;
    }
    }
    }

    Все хорошо для чисел int, но требуется, чтобы метод Sort() мог сортировать любые объекты. Другими словами, если клиентский код передает массив структур Currency или любых других классов и структур, которые он смог определить, мы должны суметь отсортировать его. Это приводит к появлению проблемы в строке if (j>i) кода, так как она требует сравнения двух объектов массива для оппеделения того, какой из них больше. Мы можем выполнить это сравнение для чисел int, но как мы сделаем это для класса, который ранее нам не встречался? Ответ заключается в том, что клиентский код, которому известно о существовании этого класса, передаст в наш код делегата, который оборачивает метод, выполняющий сравнение.
    Определим этого делегата как:

    delegate bool CompareOp(object lhs, object rhs);

    А метод Sort() будет иметь сигнатуру:

    static public void Sort(object [] sortArray, CompareOp rhsIsGreater)

    В документации для этого метода будет отмечено, что rhsIsGreater должен ссылаться на статический метод, принимающий два аргумента и возвращающий true в том случае, если значение второго аргумента “больше” (т.е. он должен следовать в массиве позже), чем значение первого.
    Теперь определим класс BubbleSorter:

    class BubbleSorter{
    static public void Sort(object [] sortArray, CompareOp rhsIsGreater){
    for (int i=0; i for (int j=0; j if (rhsIsGreater(sortArray[i], sortArray[j]){
    object temp = sortArray[i];
    sortArray[i] = sortArray[j];
    sortArray[j] = temp;
    }
    }
    }
    }
    }

    Для того чтобы использовать этот класс, необходимо определить другой класс, в котором можно создать массив, требующий сортировки. Предположим, что наша компания сотовой связи Mortimer Phones имеет список работников и желает отсортировать его по их зарплатам. Каждый из работников представлен экземпляром класса Employee, который выглядит следующим образом:

    class Employee{
    private string name;
    private decimal salary;
    public Employee(string name, decimal salary){
    this.name = name;
    this.salary = salary;
    }
    public override string ToString(){
    return string.Format(name + “, {0:C}”, salary);
    }
    public static bool RhsIsGreater (object lhs, object rhs){
    Employee Lhs = (Employee)lhs;
    Employee Rhs = (Employee)rhs;
    return (Rhs.Salary > Lhs.Salary) ? true : false;
    }
    }

    Для того чтобы добиться соответствия сигнатуре делегата CompareOp, нам пришлось определить RhsisGreater в этом классе как принимающий в качестве параметров две ссылки на object, а не на Employee. Это означает, что для выполнения сравнения мы должны привести параметры к ссылкам Employee.
    Теперь можно написать клиентский код, который будет выполнять сортировку.

    using System;
    namespace BubbleSorrer{
    delegate bool CompareOp(object lhs, object rhs);
    class Class1{
    static void Main(string[] args){
    Employee [] employees =
    {
    new Employee(”Karli Watson”, 20000),
    new Employee(”Bill Gates”, 10000),
    new Employee(”Simon Robinson”, 25000),
    new Employee(”Mortimer”, (decimal)1000000.38),
    new Employee(”Arabel Jones”, 23000),
    new Employee(”Avon from ‘Blake’s 7′”, 50000)
    };
    CompareOp EmployeeCompareOp = new CompareOp(Employee.RhsisGreater);
    BubbleSorter.Sort(employees, EmployeeCompareOp);
    for (int I=0; I Console.WriteLine (employees [I] .ToString()) ;
    }
    }
    }

    Оставить комментарий

    Вы должны авторизоваться для отправки комментария.