繁体   English   中英

函数中数组参数长度的默认参数值

[英]Default parameter value of array parameter length in a function

我创建了一个函数,该函数对传递给函数的数组进行快速排序,但由于该函数是递归函数,它需要 2 个额外的参数来帮助快速排序。

在每一轮函数之后,它将左或右设置为下一个要排序的区域,依此类推。

由于这些额外的参数,每次我手动调用函数进行快速排序时,我都需要添加 0 和数组长度作为参数。

Quicksort(arr, 0, arr.Length);

这似乎可以避免,但只需向左侧参数 (0) 添加默认值,但右侧参数需要是数组的长度,在这种情况下称为elements ,它将是:

public static void QuickSort<T>(T[] elements, int left = 0, int right = elements.Length) where T : IComparable

但无法获取元素数组的长度。

我考虑过创建一个函数来简单地插入 0 和数组的长度而不是我,但如果可能的话,我想找到一种方法来做到这一点而无需额外的函数。

public static void QuickSort<T>(T[] elements, int left, int right) where T : IComparable
{
    int i = left, j = right;
    T pivot = elements[(left + right) / 2];

    while (i <= j)
    {
        while (elements[i].CompareTo(pivot) < 0)
            i++;

        while (elements[j].CompareTo(pivot) > 0)
            j--;

        if (i <= j)
        {
            T tmp = elements[i];
            elements[i++] = elements[j];
            elements[j--] = tmp;
        }
    }
    if (left < j)
        QuickSort(elements, left, j);

    if (i < right)
        QuickSort(elements, i, right);
}

有时最简单的解决方案是最好的解决方案:添加重载。

public static void QuickSort<T>(T[] elements, int left = 0) where T : IComparable
{
    QuickSort(elements, left, elements.Length);
}

public static void QuickSort<T>(T[] elements, int left, int right) where T : IComparable
{
    // code
}

丑陋的解决方案(使用可为空的类型并使用Length更改null值)。 null不属于right的法律领域,所以没有什么大问题:

public static void QuickSort<T>(T[] elements, int left = 0, int rightTemp = null) where T : IComparable
{
    int right = rightTemp ?? elements.Length;

    // code
}

更丑的解决方案(使用-1作为“要替换的值”)。 -1 (或int.MinValue )不属于right的法律领域,但这个解决方案非常丑陋:-)

public static void QuickSort<T>(T[] elements, int left = 0, int right = -1) where T : IComparable
{
    if (right == -1)
    {
        right = elements.Length;
    }

    // code
}

您需要一个具有漂亮、干净、最小签名的方法来向外界公开,以及一个私有递归方法来进行排序。

所以:

// this method is exposed to the outside world.
// Nobody needs to know about "left" and "right".
// Consumers of this method just want to "QuickSort" some elements. 
public static void QuickSort<T>(T[] elements) where T : IComparable
{
    // init the recursion here and forget about it
    QuickSortInternal(elements, 0 , elements.Length);
}

// this is your recursive method
private static void QuickSortInternal<T>(T[] elements, int left, int right) where T : IComparable
{
    // your code....
}

由于您始终将数组本身作为第一个参数发送,因此无论如何您都有长度。 如果您可以从第一个参数中获取数组的长度,为什么还要发送长度?

换句话说,稍微更改一下代码,以便对 Quicksort 的每次调用仅通过一个数组发送。 根本不发送左右。 拆分你在每次调用中得到的数组,然后将拆分后的数组发送给两个子 Quicksort 调用,而不是每次都发送左右。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM