在Java中使用MergeSort:
public void mergeSort(int[] A)
{
if (A.length > 1)
{
int q = A.length/2;
int[] leftArray = Arrays.copyOfRange(A, 0, q);
int[] rightArray = Arrays.copyOfRange(A,q,A.length);
mergeSort(leftArray);
mergeSort(rightArray);
merge(A,leftArray,rightArray);
}
}
上面代码中的递归在Java中运行良好。
因此,为了好奇,我想将函数Arrays.copyOfRange从java转换为c#。 C#中的Array.copy有五个参数。你知道c#中的任何更简单的函数都可以从位置x到y(比如java)开始获取数组的某些元素。
在c#中,我将上述方法编码为:
public void mergeSort(int[] A)
{
if (A.Length > 1)
{
int q = A.Length / 2;
int[] leftArray = new int[q];
int[] rightArray = new int[A.Length];
for (int i = 0; i < q; i++)
{
leftArray[i] = A[i];
Console.WriteLine(leftArray[i]);
}
for (int i = q; i < A.Length; i++)
{
rightArray[i] = A[i];
Console.WriteLine(rightArray[i]);
}
Console.ReadKey();
mergeSort(leftArray);
mergeSort(rightArray);
merge(A, leftArray, rightArray);
}
}
正如您所看到的,我已经用Java中的两个循环替换了Java中的Arrays.copyOfRange函数,这在c#中没有递归。 无论如何调用mergeSort(leftArray)和mergeSort(rightArray),它都会在c#中打印出来:
由于StackOverflowException !!
,进程终止如何更好地了解如何在c#中获取某些元素?
答案 0 :(得分:7)
问题是移植的阵列副本不做同样的事情。
如果输入[a,b,c,d,e,f]
,则Java代码创建两个数组[a,b,c]
和[d,e,f]
,而C#端口创建两个数组[a,b,c]
和{{1} }。值得注意的是,
[0,0,0,d,e,f]
)。这是导致StackOverflowException从未到达终止案例的原因,并且;; new int[A.Length]
索引开始的值,该索引是中途索引。使用Array.Copy
考虑这种替换方法 - 具有相同签名的方法可以用作移植代码中的替换,只要方法中的内容与原始内容具有相同的效果。
q
或者,使用循环但在原始端口中没有问题的版本。使用谨慎功能的另一个原因 - 它使任务易于查看和推理。能够消除重复代码并没有伤害。
int[] copyOfRange (int[] src, int start, int end) {
int len = end - start;
int[] dest = new int[len];
Array.Copy(src, start, dest, 0, len);
return dest;
}
如果你像我一样懒惰,也可以使用LINQ轻松编写代码。
int[] copyOfRange (int[] src, int start, int end) {
int len = end - start;
int[] dest = new int[len];
// note i is always from 0
for (int i = 0; i < len; i++)
{
dest[i] = src[start + i]; // so 0..n = 0+x..n+x
}
return dest;
}