Как пройти по ссылке в C # - PullRequest
0 голосов
/ 17 мая 2019

Я пишу класс быстрой сортировки, имитирующий код, указанный в «Алгоритмах 4» Седжвиком.Оригинальный код написан на Java.Я перевел на C # основную часть, но, похоже, она не работает.Кажется, проблема в строке a = a.OrderBy(x => r.Next()).ToArray(), но я не знаю, как ее исправить.

Я пытался добавить ref в сигнатуры методов Sort s и Partition, но один разЯ вызываю функцию Sort(ref a) в Main, компилятор жалуется, что cannot converte ref System.String[] to ref System.IComparable[].Я также пытался заставить первый Sort вернуть IComparable[], отсортированный массив.Однако, когда я вызываю его в Main как этот string[] nums = (string[]) Sort(nums), он выдает ошибку времени выполнения: Unable to cast object of type 'System.IComparable[]' to type 'System.String[]'.

public class Quick
{
    public static void Sort(IComparable[] a)
    {
        Random r = new Random();
        a = a.OrderBy(x => r.Next()).ToArray();
        Sort(a, 0, a.Length - 1);
    }

    private static void Sort(IComparable[] a, int lo, int hi)
    {
        if (lo >= hi) return;
        int p = Partition(a, lo, hi);
        Sort(a, lo, p - 1);
        Sort(a, p + 1, hi);
    }

    private static int Partition(IComparable[] a, int lo, int hi)
    {
        int i = lo, j = hi;
        IComparable p = a[lo];
        while (true)
        {
            while (Less(a[++i], p))
            {
                if (i == hi)
                    break;
            }

            while (Less(p, a[--j]))
            {
                if (j == lo)
                    break;
            }

            if (i >= j) break;

            Exch(a, i, j);
        }
        Exch(a, lo, j);
        return j;
    }

    private static void Exch(IComparable[] a, int lo, int hi)
    {
        IComparable tmp = a[lo];
        a[lo] = a[hi];
        a[hi] = tmp;
    }

    private static bool Less(IComparable a, IComparable b)
    {
        return a.CompareTo(b) < 0;
    }


    public static void Main(string[] args)
    {
        string[] nums = File.ReadAllLines(args[0]);
        for (int i = 0; i < nums.Length; i++)
        {
            Console.WriteLine(nums[i]);
        }
        Sort(nums);
        Console.WriteLine("After sorting:");
        for (int i = 0; i < nums.Length; i++)
        {
            Console.WriteLine(nums[i]);
        }
        Console.ReadKey();
    }
}

Вторая строка WriteLine должна распечатать отсортированный массив, но это не так.

Ответы [ 2 ]

2 голосов
/ 17 мая 2019

Проблема здесь не в передаче по ссылке, а в этой строке, как вы определили:

a = a.OrderBy(x => r.Next()).ToArray();

Вы даете a новое значение, которое отличается от простого изменения содержимого a. Поскольку метод Sort сортирует массив на месте, вам не нужно создавать новый массив, и массив не нужно перетасовывать перед его сортировкой.

Итак, удаление этих двух строк должно заставить ваш код работать:

Random r = new Random();
a = a.OrderBy(x => r.Next()).ToArray();

Кажется, вы столкнулись с некоторыми проблемами при попытке вернуть массив из Sort. Вы можете исправить это, сделав все ваши методы общими, с общим параметром T, ограниченным IComparable<T>:

public static T[] Sort<T>(T[] a) where T: IComparable<T>
{
    Random r = new Random();
    a = a.OrderBy(x => r.Next()).ToArray();
    Sort(a, 0, a.Length - 1);
    return a;
}

private static void Sort<T>(T[] a, int lo, int hi) where T: IComparable<T>
{
    if (lo >= hi) return;
    int p = Partition(a, lo, hi);
    Sort(a, lo, p - 1);
    Sort(a, p + 1, hi);
}

private static int Partition<T>(T[] a, int lo, int hi) where T: IComparable<T>
{
    int i = lo, j = hi;
    T p = a[lo];
    while (true)
    {
        while (Less(a[++i], p))
        {
            if (i == hi)
                break;
        }

        while (Less(p, a[--j]))
        {
            if (j == lo)
                break;
        }

        if (i >= j) break;

        Exch(a, i, j);
    }
    Exch(a, lo, j);
    return j;
}

private static void Exch<T>(T[] a, int lo, int hi)
{
    T tmp = a[lo];
    a[lo] = a[hi];
    a[hi] = tmp;
}

private static bool Less<T>(T a, T b) where T: IComparable<T>
{
    return a.CompareTo(b) < 0;
}
0 голосов
/ 17 мая 2019

Вам нужно вернуть отсортированный массив, так как, как вы сказали, он передается по значению, а не по ссылке.Добавьте тип возврата вместо void в метод Sort и верните a;

И измените

Sort (числа);

на

nums = Sort (НУМС);

...