不使用Array.Reverse()反转数组

xor*_*wer 14 c# arrays reverse

如何在不使用Array.Reverse()方法的情况下反转数组(在C#中)?

例如,

int[] arr = {1,3,4,9,8};
// some code here
Console.WriteLine(string.Join(",", arr));
Run Code Online (Sandbox Code Playgroud)

应该导致

8,9,4,3,1
Run Code Online (Sandbox Code Playgroud)

我把这作为面试任务.

Pet*_*hev 39

代替// some code here问题的代码是:

for (int i = 0; i < arr.Length / 2; i++)
{
   int tmp = arr[i];
   arr[i] = arr[arr.Length - i - 1];
   arr[arr.Length - i - 1] = tmp;
}
Run Code Online (Sandbox Code Playgroud)

您应该只遍历数组的前半部分(arr.Length / 2).如果遍历整个数组(arr.Length),它将被反转两次,产生与它开始之前相同的元素顺序.


Pal*_*lec 9

基本上,要求您重新实现Array.Reverse(Array)。如果您看一下它是如何在框架本身中实现的,而忽略了许多技术细节,您会发现它只是在整个数组上调用其三参数版本(反转了数组的指定部分)。

Array.Reverse(Array,Int32,Int32) 是一个while循环,用于交换元素并维护两个索引:

  1. i 指向反转部分的第一个元素,并且
  2. j 指向反转部分的最后一个元素。

重写以代替// some code here以下问题:

int i = 0;
int j = arr.Length - 1;
while (i < j)
{
    var temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
    i++;
    j--;
}
Run Code Online (Sandbox Code Playgroud)

这比使用for循环的实现更容易掌握,执行的算法更少,并且优雅地避免了使用双重还原的问题。

  • 顺便说一句,CoreCLR添加了一个通用的`Array.Reverse &lt;T&gt;()`,它的性能更好,并且[读取起来更简单](https://github.com/dotnet/coreclr/blob/ea9bee5ac2f96a1ea6b202dc4094b8d418d9209c/src/mscorlib/src /System/Array.cs#L1704-L1713)。它是在[issue#2352](https://github.com/dotnet/corefx/issues/2352)中提出的。 (2认同)