函数中数组参数长度的默认参数值
Default parameter value of array parameter length in a function
我创建了一个函数,可以对传递给该函数的数组进行快速排序,但由于该函数是递归函数,它需要 2 个额外的参数来帮助进行快速排序。
在每一轮函数之后,它将 left 或 right 设置为下一个要排序的区域,依此类推。
由于这些额外的参数,每次我手动调用函数进行快速排序时,我都需要添加 0 和数组长度作为参数。
Quicksort(arr,0,arr.Length);
现在这似乎可以避免,只需将默认值添加到左侧参数 (0),但右侧参数需要是数组的长度,在这种情况下称为元素,它将是:
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
}
丑陋的解决方案(使用可空类型并将 null
值更改为 Length
)。 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 作为 "value-to-be-replaced")。 -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
}
因为你总是通过数组本身作为第一个参数发送,所以你有长度。如果您可以从第一个参数中获取数组的长度,为什么还要发送长度?
换句话说,稍微更改一下代码,以便每次调用 Quicksort 时只发送一个数组。根本不要左右发送。每次调用时拆分你得到的数组,然后将拆分后的数组发送给两个子Quicksort调用,而不是每次都发送left和right。
您需要一个具有良好、干净、最小签名的方法来向外界公开,以及一个私有递归方法来进行排序。
所以:
// 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....
}
我创建了一个函数,可以对传递给该函数的数组进行快速排序,但由于该函数是递归函数,它需要 2 个额外的参数来帮助进行快速排序。 在每一轮函数之后,它将 left 或 right 设置为下一个要排序的区域,依此类推。
由于这些额外的参数,每次我手动调用函数进行快速排序时,我都需要添加 0 和数组长度作为参数。
Quicksort(arr,0,arr.Length);
现在这似乎可以避免,只需将默认值添加到左侧参数 (0),但右侧参数需要是数组的长度,在这种情况下称为元素,它将是:
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
}
丑陋的解决方案(使用可空类型并将 null
值更改为 Length
)。 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 作为 "value-to-be-replaced")。 -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
}
因为你总是通过数组本身作为第一个参数发送,所以你有长度。如果您可以从第一个参数中获取数组的长度,为什么还要发送长度?
换句话说,稍微更改一下代码,以便每次调用 Quicksort 时只发送一个数组。根本不要左右发送。每次调用时拆分你得到的数组,然后将拆分后的数组发送给两个子Quicksort调用,而不是每次都发送left和right。
您需要一个具有良好、干净、最小签名的方法来向外界公开,以及一个私有递归方法来进行排序。
所以:
// 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....
}