Как отсортировать массив по двум и более критериям с помощью MergeSort? - PullRequest
0 голосов
/ 11 июля 2020

Учитывая, что у меня есть массив объектов класса Example со свойствами A и B:

    public class Example
    {
        public int A { get; set; }
        public int B { get; set; }

        public Example(int a, int b)
        {
            A = a;
            B = b;
        }
    }

Как я могу отсортировать массив в порядке возрастания по A и, когда два или более элемента равны , сортировать по B между ними? Я использую этот пример алгоритма MergeSort .

    public void Run()
    {
        Example[] example = new Example[5] {
            new Example(500, 25),
            new Example(100, 5),
            new Example(500, 20),
            new Example(300, 15),
            new Example(500, 35)
        };

        MergeSort(example, 0, example.Length - 1);
    }

Метод сортировки:

    public void MergeSort(Example[] input, int left, int right)
    {
        if (left < right)
        {
            int middle = (left + right) / 2;

            MergeSort(input, left, middle);
            MergeSort(input, middle + 1, right);

            Merge(input, left, middle, right);
        }
    }

    private void Merge(Example[] input, int left, int middle, int right)
    {
        Example[] leftArray = new Example[middle - left + 1];
        Example[] rightArray = new Example[right - middle];

        Array.Copy(input, left, leftArray, 0, middle - left + 1);
        Array.Copy(input, middle + 1, rightArray, 0, right - middle);

        int i = 0;
        int j = 0;
        for (int k = left; k < right + 1; k++)
        {
            if (i == leftArray.Length)
            {
                input[k] = rightArray[j];
                j++;
            }
            else if (j == rightArray.Length)
            {
                input[k] = leftArray[i];
                i++;
            }
            else if (leftArray[i].A <= rightArray[j].A)
            {
                input[k] = leftArray[i];
                i++;
            }
            else
            {
                input[k] = rightArray[j];
                j++;
            }
        }
    }

Я не уверен, действительно ли это MergeSort, но он работает аналогичным образом. Раздел, определяющий порядок, следующий:

    else if (leftArray[i].A <= rightArray[j].A)
    {
        input[k] = leftArray[i];
        i++;
    }

Ответы [ 2 ]

0 голосов
/ 11 июля 2020

Обычный способ обработки такого рода вещей - процедура, которая сравнивает два объекта, передается в процедуру сортировки.

Как вы уже поняли, процедура сравнения проверяет A, если A соответствует ей проверяет B. (Лично я дошел до F, хотя и представить себе не могу, что в производстве он когда-либо зашел так далеко).

0 голосов
/ 11 июля 2020

Подумав еще немного и сделав несколько попыток, я понял, что решение очень простое. Для каждого дополнительного критерия просто добавьте блок условий для сравнения, если свойства предыдущего блока равны, и повторите то же сравнение предыдущего блока для новых свойств. В моем случае код выглядит так:

    else if (leftArray[i].A < rightArray[j].A)
    {
        input[k] = leftArray[i];
        i++;
    }
    else if ((leftArray[i].A == rightArray[j].A) && (leftArray[i].B <= rightArray[j].B))
    {
        input[k] = leftArray[i];
        i++;
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...