From 47b5c3654288626843b7e6c7bb7e639c81f06641 Mon Sep 17 00:00:00 2001 From: Jidong Xiao Date: Tue, 26 Sep 2023 18:18:25 -0400 Subject: [PATCH] adding code files --- labs/05_vectors/test_vec.cpp | 97 ++++++++++++++++++++++++ labs/05_vectors/vec.h | 142 +++++++++++++++++++++++++++++++++++ 2 files changed, 239 insertions(+) create mode 100644 labs/05_vectors/test_vec.cpp create mode 100644 labs/05_vectors/vec.h diff --git a/labs/05_vectors/test_vec.cpp b/labs/05_vectors/test_vec.cpp new file mode 100644 index 0000000..2777add --- /dev/null +++ b/labs/05_vectors/test_vec.cpp @@ -0,0 +1,97 @@ +#include +#include +using namespace std; + +#include "vec.h" + +int main() { + + // --------------------------------------------------- + // initialize v1 with 10 values... the multiples of 5 + Vec v1( 10, 0 ); + Vec::size_type i; + for ( i = 0; i < v1.size(); i++) { + v1[i] = 5 * i; + } + cout << "v1.size() = " << v1.size() << ". Should be 10.\n"; + cout << "Contents of v1 (multiples of 5):"; + for ( i = 0; i v2( v1 ); + v2[ 9 ] = v2[ 0 ]; + v2[ 8 ] = v2[ 1 ]; + v2[ 7 ] = v2[ 2 ]; + v2[ 6 ] = v2[ 3 ]; + v2[ 5 ] = v2[ 4 ]; + cout << "Contents of v1 (still multiples of 5):"; + for ( i = 0; i v3; + v3 = v2; + v3.clear(); + cout << "\nAfter copying v2 to v3 and clearing v3, v2.size() = " + << v2.size() << " and v3.size() = " << v3.size() << endl; + cout << "Contents of v2 (should be unchanged):"; + for ( i = 0; i z; + for ( i = 0; i<5; ++i ) + z.push_back( sqrt( double(10*(i+1)) )); + cout << "Contents of vector z: "; + for ( Vec::size_type j = 0; j < z.size(); j++ ) + cout << " " << z[j]; + cout << endl; + + + + // ADD MORE TEST CASES HERE + + + return 0; +} diff --git a/labs/05_vectors/vec.h b/labs/05_vectors/vec.h new file mode 100644 index 0000000..529aabf --- /dev/null +++ b/labs/05_vectors/vec.h @@ -0,0 +1,142 @@ +#ifndef Vec_h_ +#define Vec_h_ +// Simple implementation of the vector class, revised from Koenig and Moo. This +// class is implemented using a dynamically allocated array (of templated type T). +// We ensure that that m_size is always <= m_alloc and when a push_back or resize +// call would violate this condition, the data is copied to a larger array. + +template class Vec { + +public: + // TYPEDEFS + typedef T* iterator; + typedef const T* const_iterator; + typedef unsigned int size_type; + + // CONSTRUCTORS, ASSIGNMNENT OPERATOR, & DESTRUCTOR + Vec() { this->create(); } + Vec(size_type n, const T& t = T()) { this->create(n, t); } + Vec(const Vec& v) { copy(v); } + Vec& operator=(const Vec& v); + ~Vec() { delete [] m_data; } + + // MEMBER FUNCTIONS AND OTHER OPERATORS + T& operator[] (size_type i) { return m_data[i]; } + const T& operator[] (size_type i) const { return m_data[i]; } + void push_back(const T& t); + iterator erase(iterator p); + void resize(size_type n, const T& fill_in_value = T()); + void clear() { delete [] m_data; create(); } + bool empty() const { return m_size == 0; } + size_type size() const { return m_size; } + + // ITERATOR OPERATIONS + iterator begin() { return m_data; } + const_iterator begin() const { return m_data; } + iterator end() { return m_data + m_size; } + const_iterator end() const { return m_data + m_size; } + +private: + // PRIVATE MEMBER FUNCTIONS + void create(); + void create(size_type n, const T& val); + void copy(const Vec& v); + + // REPRESENTATION + T* m_data; // Pointer to first location in the allocated array + size_type m_size; // Number of elements stored in the vector + size_type m_alloc; // Number of array locations allocated, m_size <= m_alloc +}; + +// Create an empty vector (null pointers everywhere). +template void Vec::create() { + m_data = NULL; + m_size = m_alloc = 0; // No memory allocated yet +} + +// Create a vector with size n, each location having the given value +template void Vec::create(size_type n, const T& val) { + m_data = new T[n]; + m_size = m_alloc = n; + for (T* p = m_data; p != m_data + m_size; ++p) + *p = val; +} + +// Assign one vector to another, avoiding duplicate copying. +template Vec& Vec::operator=(const Vec& v) { + if (this != &v) { + delete [] m_data; + this -> copy(v); + } + return *this; +} + +// Create the vector as a copy of the given vector. +template void Vec::copy(const Vec& v) { + this->m_alloc = v.m_alloc; + this->m_size = v.m_size; + this->m_data = new T[this->m_alloc]; + + // Copy the data + for (size_type i = 0; i < this->m_size; ++i) + this -> m_data[ i ] = v.m_data[ i ]; +} + +// Add an element to the end, resize if necesssary. +template void Vec::push_back(const T& val) { + if (m_size == m_alloc) { + // Allocate a larger array, and copy the old values + + // Calculate the new allocation. Make sure it is at least one. + m_alloc *= 2; + if (m_alloc < 1) m_alloc = 1; + + // Allocate and copy the old array + T* new_data = new T[ m_alloc ]; + for (size_type i=0; i typename Vec::iterator Vec::erase(iterator p) { + // remember iterator and T* are equivalent + for (iterator q = p; q < m_data+m_size-1; ++q) + *q = *(q+1); + m_size --; + return p; +} + +// If n is less than or equal to the current size, just change the size. If n is +// greater than the current size, the new slots must be filled in with the given value. +// Re-allocation should occur only if necessary. push_back should not be used. +template void Vec::resize(size_type n, const T& fill_in_value) { + if (n <= m_size) + m_size = n; + else { + // If necessary, allocate new space and copy the old values + if (n > m_alloc) { + m_alloc = n; + T* new_data = new T[m_alloc]; + for (size_type i=0; i