1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
|
#include <iostream>
#include "IntArray.h"
#include "ArrayException.h"
IntArray::IntArray()
{
m_nLength = 0;
m_pnData = 0;
}
IntArray::IntArray(const int nLength)
:m_pnData{ new int[nLength] }, m_nLength{ nLength }
{
}
IntArray::~IntArray()
{
delete[] m_pnData;
}
void IntArray::Erase()
{
delete[] m_pnData;
m_pnData = 0;
m_nLength = 0;
}
int& IntArray::operator[](const int nIndex)
{
if (nIndex < 0 || nIndex >= m_nLength)
{
throw ArrayException{ "Invalid index" };
}
return m_pnData[nIndex];
}
int IntArray::GetLength() const
{
return m_nLength;
}
// Reallocate resizes the array. Any existing elements will be destroyed.
// This function operates quickly.
void IntArray::Reallocate(const int nNewLength)
{
// First we delete any existing elements
Erase();
// If our array is going to be empty now, return here
if (nNewLength <= 0)
{
return;
}
// Then we have to allocate new elements
m_pnData = new int[nNewLength];
m_nLength = nNewLength;
}
// Resize resizes the array. Any existing elements will be kept.
// This function operates slowly.
void IntArray::Resize(const int nNewLength)
{
// If we are resizing to an empty array, do that and return
if (nNewLength <= 0)
{
Erase();
return;
}
// Now we can assume nNewLength is at least 1 element. This algorithm
// works as follows: First we are going to allocate a new array. Then we
// are going to copy elements from the existing array to the new array.
// Once that is done, we can destroy the old array, and make m_pnData
// point to the new array.
// First we have to allocate a new array
int *pnData = new int[nNewLength];
// Then we have to figure out how many elements to copy from the existing
// array to the new array. We want to copy as many elements as there are
// in the smaller of the two arrays.
if (m_nLength > 0)
{
int nElementsToCopy = (nNewLength > m_nLength) ? m_nLength : nNewLength;
// Now copy the elements one by one
for (int nIndex = 0; nIndex < nElementsToCopy; nIndex++)
{
pnData[nIndex] = m_pnData[nIndex];
}
}
// Now we can delete the old array because we don't need it any more
delete[] m_pnData;
// And use the new array instead! Note that this simply makes m_pnData point
// to the same address as the new array we dynamically allocated. Because
// pnData was dynamically allocated, it won't be destroyed when it goes out of scope.
m_pnData = pnData;
m_nLength = nNewLength;
}
void IntArray::InsertBefore(const int nValue, const int nIndex)
{
// Sanity check our nIndex value
if (nIndex < 0 || nIndex >= m_nLength)
{
throw ArrayException{ "Invalid index" };
}
// First create a new array one element larger than the old array
int *pnData = new int[m_nLength + 1];
// Copy all of the elements up to the index
for (int nBefore = 0; nBefore < nIndex; nBefore++)
{
pnData[nBefore] = m_pnData[nBefore];
}
// Insert our new element into the new array
pnData[nIndex] = nValue;
// Copy all of the values after the inserted element
for (int nAfter = nIndex; nAfter < m_nLength; nAfter++)
{
pnData[nAfter + 1] = m_pnData[nAfter];
}
// Finally, delete the old array, and use the new array instead
delete[] m_pnData;
m_pnData = pnData;
m_nLength += 1;
}
void IntArray::Remove(const int nIndex)
{
// Sanity check our nIndex value
if (nIndex < 0 || nIndex >= m_nLength)
{
throw ArrayException{ "Invalid index" };
}
// First create a new array one element smaller than the old array
int *pnData = new int[m_nLength - 1];
// Copy all of the elements up to the index
for (int nBefore = 0; nBefore < nIndex; nBefore++)
{
pnData[nBefore] = m_pnData[nBefore];
}
// Copy all of the values after the removed element
for (int nAfter = nIndex + 1; nAfter < m_nLength; nAfter++)
{
pnData[nAfter - 1] = m_pnData[nAfter];
}
// Finally, delete the old array, and use the new array instead
delete[] m_pnData;
m_pnData = pnData;
m_nLength -= 1;
}
void IntArray::InsertAtBeginning(const int nValue)
{
InsertBefore(nValue, 0);
}
void IntArray::InsertAtEnd(const int nValue)
{
InsertBefore(nValue, m_nLength);
}
int IntArray::GetElement(const int nIndex) const
{
return m_pnData[nIndex];
}
std::ostream& operator<< (std::ostream &out, const IntArray &anArray)
{
out << anArray.m_pnData;
return out;
}
|