Reputation: 149
This is my first attempt of reversing a dynamic array:
bool reverse()
{
T *newArray = NULL;
// Validate operation.
if (!isValid() || isReadOnly())
return false;
// Allocate new array
newArray = new (std::nothrow)T[m_size];
if (newArray == NULL)
return false;
// Reverse the array's contents.
for (int i = m_size - 1; i >= 0; i--)
newArray[i] = m_array[i];
// Delete old array.
delete[] m_array;
m_array = NULL;
// Assign new array
m_array = newArray;
return true;
}
As you can imagine, this is very costly for large arrays:
I'm aware of std::reverse, but unfortunately it doesn't work on dynamic arrays.
Should I use std::vector? Yes. But this is for learning. I'm reading from a data structures game programming book and extending my learning.
So I'm interested in reducing this member function of Array to the algorithm itself:
// Reverse the array's contents.
for (int i = m_size - 1; i >= 0; i--)
newArray[i] = m_array[i];
I feel like there's an easy way to go about this that is much less costly. I looked on Google but I'm just finding solutions for static arrays.
Extra:
I'm trying std::reverse again, but no luck so far.
std::reverse(std::begin(m_array), std::end(m_array));
Error on compile:
error C2672: 'begin': no matching overloaded function found
Also, std::end wouldn't know the end of a dynamic array, as no size is specified, so maybe I'm just using the wrong functions to achieve this goal. It'd be nice to use std::reverse somehow.
Upvotes: 1
Views: 2278
Reputation: 19033
It works fine as you can use pointers with every std function which can use iterators:
int size = 10;
int *i = new int[size];
iota(i, i + size, 0);
copy(i, i + size, ostream_iterator<int>(cout, " "));
reverse(i, i + size);
copy(i, i + size, ostream_iterator<int>(cout, " "));
0 1 2 3 4 5 6 7 8 9 9 8 7 6 5 4 3 2 1 0
You can check this article Raw pointers are also Iterators!.
Upvotes: 1
Reputation: 1013
You could manually swap the starting indices with the ending indices to effectively reverse the array.
#include <iostream>
#include <string>
#include <algorithm>
int main()
{
int* array = new int[6]{ 1, 2, 3, 4, 5, 6 };
constexpr std::size_t size = 6;
//swap ending and starting iterators
for (std::size_t index = 0, end = size / 2; index != end; ++index) {
std::swap(array[index], array[size - index - 1]);
}
for (std::size_t index = 0; index != size; ++index) {
std::cout << array[index] << ' ';
}
std::cout << std::endl << std::endl;
std::reverse(array, array + size);
for (std::size_t index = 0; index != size; ++index) {
std::cout << array[index] << ' ';
}
delete[] array;
return 0;
}
std::reverse
Will also work since it accepts a starting and ending iterator to which pointers can act as iterators.
Upvotes: 1
Reputation: 66922
std::reverse(m_array+0, m_array+m_size);
std::reverse
takes iterators as parameters, and pointers are one form of iterator.
Upvotes: 7