Reputation: 1208
I've never programmed in C++ before and I'm trying to figure out how to recursively pass segments of an array in a C++ method. I am trying to convert the following pseudo code into C++.
SlowSort(A[1...n])
if n = 2
if A[1] > A[2]
Swap(A[1], A[2])
else if n > 2
SlowSort(A[1...(2n/3)])
SlowSort(A[(n/3+1)... n])
SlowSort(A[1...(2n/3)])
The recursive calls are the bits I'm having a problem with. I was thinking about creating two new arrays that point to the wanted locations but don't know how to go about that, specifically doing that and defining the length of the array. I've tried googling it and searching this site, but there doesn't seem to be anything, that I understand, on it. Also, in case I fudged up somewhere in my code, here's what I have for the first bit.
int SlowSort(int A[])
{
int length = (sizeof(A)/sizeof(*A));
if(length ==2)
{
if(A[0] > A[1])
{
int temp = A[0];
A[0] = A[1];
A[1] = temp;
}
}
In short, how do In covert the else if statement into C++? Explanation would be nice too.
Thanks
Upvotes: 1
Views: 203
Reputation: 275966
The modern C++ way to do this would be to pass iterators to the beginning and one-past-the-end of the range. In this case, the iterators are pointers.
void SlowSort(int* begin, int* end)
{
unsigned length = end-begin;
if(length == 2)
{
if(begin[0] > begin[1])
{
std::swap( begin[0], begin[1] );
}
} else if(length>2) {
SlowSort(begin, begin+2*length/3);
SlowSort(begin+length/3, end);
SlowSort(begin, begin+2*length/3);
}
}
then, for the case of working with an entire array:
template<unsigned N>
void SlowSort( int(&Arr)[N] ) {
return SlowSort( Arr, Arr+N );
}
we dispatch it to the iterator version, relying on decaying of array-to-pointer. This has to be a template
function, as we want it to work with multiple different array sizes.
Note that an int Arr[]
is not an array. It is a different way to say int* Arr
, left over as a legacy from C. In fact, as a parameter to a function, saying void foo( int A[27] )
results in void foo( int* A )
: function parameters cannot be arrays.
They can, however, be references-to-arrays, which is what the above template
function uses.
Upvotes: 2
Reputation: 3205
This is pretty simple. Since arrays are just consecutive pointers. If you have a method:
Your code would look like this:
void slowSort(int[] array, int length)
{
if(length == 2)
{
if(array[0] > array[1])
{
int temp = array[0];
array[0] = array[1];
array[1] = temp;
}
}
else
{
slowSort(&array[0], (2 * length) / 3 - 1);
slowSort(&array[length / 3], length - (length / 3 - 1));
slowSort(&array[0], (2 * length) / 3 - 1);
}
}
The trick I use here is that I pass the pointer of the element I want to start with and the pass the end point.
This works because when you pass an array in C++ you just pass the pointer of the first element. Here I pass a custom pointer of the array.
Upvotes: 2
Reputation: 311146
You simply pass required pointer using the pointer arithmetic. For example the following pseudo code
SlowSort(A[(n/3+1)... n])
could be written as
SlowSort( A + n/3+1, n - n/3 - 1 );
So the function could be declared as
void SlowSort( int A[], size_t n );
As for this code snippet
int SlowSort(int A[])
{
int length = (sizeof(A)/sizeof(*A));
then it is invalid because array is implicitly converted to a ponter to its first element when it is passed as an argument to a function seclared such a way. So the value of length will not be equal to the number of elements.
Upvotes: 2
Reputation:
You will want to pass indices into the array instead, and use those.
void SlowSort(int A[], int left, int right)
{
if (right - left == 2)
if (A[left] > A[right])
Swap(A[left], A[right]);
else
{
int n = right - left + 1;
SlowSort(A, left, 2 * n / 3);
SlowSort(A, left + n / 3 + 1, right);
SlowSort(A, left, left + 2* n / 3);
}
The above code might not be correct regarding what the algorithm is supposed to do, but you get the idea I'm trying to describe. The thing is: you don't make a copy of the array. Instead, pass the same array always and the range (i.e. the indices) you are sorting.
Upvotes: 6