我正在将C ++程序转换为CSharp程序。尽管C ++和Csharp完全相同,但是C ++程序对于输入{5,4,1,3,6,7,2}的运行没有问题,而在Csharp中,存在索引超出范围的异常。我粘贴了下面的两个代码,它们是彼此的完全相同的副本,但是我不明白为什么CSharp版本中C ++运行正常时会出现异常。
C ++程序
#include <iostream>
using namespace std;
#include <stdio.h>
#include<stdlib.h>
void swap (int *x, int *y)
{
int temp = *x;
*x = *y;
*y = temp;
}
int partition (int A[], int l, int h)
{
int pivot = A[l];
int i = l, j = h;
do
{
do
{
i++;
} while (A[i] <= pivot);
do
{
j--;
} while (A[j] > pivot);
if (i < j)
swap (&A[i], &A[j]);
}
while (i < j);
swap (&A[l], &A[j]);
return j;
}
void QuickSort (int A[], int l, int h)
{
int j;
if (l < h)
{
j = partition (A, l, h);
QuickSort (A, l, j);
QuickSort (A, j + 1, h);
}
}
int main ()
{
int A[] = { 5, 4, 1, 3, 6, 7, 2 }, n = 7, i;
QuickSort (A, 0, n);
for (i = 0; i < 7; i++)
printf ("%d ", A[i]);
printf ("\n");
return 0;
}
CSharp程序
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MyApp
{
public class QuickSort2
{
int partition(int[] A, int l, int h)
{
int pivot = A[l];
int i = l, j = h;
do
{
do
{
i++;
}
while (A[i] <= pivot);
do
{
j--;
}
while (A[j] > pivot);
if (i < j)
Swap(ref A[i], ref A[j]);
}
while (i < j);
Swap(ref A[l], ref A[j]);
return j;
}
public void QuickSort(int[] A, int l, int h)
{
int j;
if (l < h)
{
j = partition(A, l, h);
QuickSort(A, l, j);
QuickSort(A, j + 1, h);
}
}
public void Swap(ref int x, ref int y)
{
int tmp = x;
x = y;
y = tmp;
}
}
}
[Test]
public void TestQuickSort2()
{
QuickSort2 quick = new QuickSort2();
int[] list = new int[] { 5, 4, 1, 3, 6, 7, 2};
quick.QuickSort(list, 0, 7);
for (int i = 0; i < 7; i++)
{
Console.Write(list[i] + " --> ");
}
}
编辑2。 问题发生在以下位置和迭代
答案 0 :(得分:0)
按照我最初的要求,问题就在那里。这句话:
do {
i++;
} while (A[i] <= pivot);
如果数组的最后一个元素低于您计算出的变量 pivot ,则将超出数组的边界。也许这可以解决问题:
do {
i++;
} while ((i <= h) && (A[i] <= pivot));
您需要在第二个循环中执行相同的操作,因此变量j不会变为负数。
答案 1 :(得分:-1)
这里的问题是C ++不会检查边界,而C#会按照@KaenbyouRin的建议进行检查。因此,添加以下边界检查可以解决该问题。
int partition(int[] A, int l, int h)
{
int pivot = A[l];
int i = l, j = h;
do
{
do
{
i++;
}
while (i < h && A[i] <= pivot); // i < h condition not needed in C++ as C++ doesnot check for array bounds but C# does
do
{
j--;
}
while (j >= l && A[j] > pivot);
if (i < j)
Swap(ref A[i], ref A[j]);
}
while (i < j);
Swap(ref A[l], ref A[j]);
return j;
}