// int_vec.cpp #include "cmpt_error.h" #include #include #include #include #include using namespace std; class int_vec { int cap; int* arr; int sz; void check_bounds(int i, const string& msg) const { if (i < 0 || i >= sz) { cmpt::error(msg); } } public: static const int default_cap = 10; // default constructor int_vec() : cap(default_cap), arr(nullptr), sz(0) { arr = new int[cap]; } int_vec(int n) : int_vec(n, 0) // constructor delegation { } // "fill" constructor, i.e. constructs an int_vec of size n ints all // initialized to fill_val. // // cap is initialized to n + 10 instead of just n so that there is a // little extra space for quickly appending new elements. int_vec(int n, int fill_val) : cap(n + default_cap), arr(nullptr), sz(n) { if (sz < 0) cmpt::error("int_vec(n, fill_val): n must be >= 0"); arr = new int[cap]; for(int i = 0; i < sz; i++) { arr[i] = fill_val; } } // copy constructor: constructs a new int_vec that is a copy of // another int_vec // // Note that since this constructor is part of the int_vec class, it has // access to any private variables in other (which is also an int_vec). // Thus this constructor can access other.sz and other.arr, even though // they're private. // // Notice also that the capacity of other ir not used: we set the capacity // to be big enough to hold all the elements in other, plus a little extra // space for quick appending. int_vec(const int_vec& other) : cap(other.sz + default_cap), arr(nullptr), sz(other.sz) { arr = new int[cap]; for(int i = 0; i < sz; i++) { arr[i] = other.arr[i]; } } // destructor ~int_vec() { delete[] arr; } // size is a getter int size() const { return sz; } int capacity() const { return cap; } // method: setter void set(int i, int val) { check_bounds(i, "set: index out of bounds"); arr[i] = val; } int get(int i) const { check_bounds(i, "get: index out of bounds"); return arr[i]; } // cout << v[2]; // getter // v[2] = 5; // setter // setter int& operator[](int i) { check_bounds(i, "operator[]: index out of bounds"); return arr[i]; } // getter int operator[](int i) const { return get(i); } // assignment int_vec& operator=(const int_vec& other) { if (this == &other) { // always check for self-assignment return *this; } else { // re-size the underlying array if necessary if (cap < other.sz) { delete arr; cap = other.sz + 10; arr = new int[cap]; } sz = other.sz; for(int i = 0; i < sz; i++) { arr[i] = other.arr[i]; } } return *this; } // adds x to the right end of this int_vec, increasing its // capacity if necessary void append(int x) { // resize arr if necessary if (size() >= capacity()) { cap = 2 * cap; int* new_arr = new int[cap]; // copy everything into new_arr for(int i = 0; i < size(); i++) { new_arr[i] = arr[i]; } delete[] arr; arr = new_arr; } assert(size() < capacity()); arr[sz] = x; sz++; } string to_string() const { if (size() == 0) { return "{}"; } else { string result = "{" + std::to_string(arr[0]); for(int i = 1; i < size(); i++) { // i=1, not 0 result += ", " + std::to_string(arr[i]); } result += "}"; return result; } } void print() const { cout << to_string(); } // void print() const { // if (size() == 0) { // cout << "{}"; // } else { // cout << "{"; // cout << arr[0]; // for(int i = 1; i < size(); i++) { // i=1, not 0 // cout << ", " (*<< arr[i]; // } // cout << "}"; // } // } void println() const { print(); cout << ", sz=" << sz << ", cap=" << cap << "\n"; } int sum1() const { int result = 0; for(int i = 0; i < size(); i++) { result += (*this)[i]; } return result; } int sum2() const { int result = 0; const int_vec& v = *this; for(int i = 0; i < size(); i++) { result += v[i]; } return result; } int sum3() const { return accumulate(arr, arr + sz, 0); } void sort() { std::sort(arr, arr + sz); } }; // class int_vec ostream& operator<<(ostream& out, const int_vec& v) { out << v.to_string(); return out; } // a == b returns true if a and b have the same elements in the same order; // otherwise it returns false bool operator==(const int_vec& a, const int_vec& b) { if (a.size() != b.size()) return false; for(int i = 0; i < a.size(); i++) { if (a.get(i) != b.get(i)) { return false; } } return true; } // not equal operator bool operator!=(const int_vec& a, const int_vec& b) { return !(a == b); } int main() { cout << "default_cap: " << int_vec::default_cap << "\n"; int_vec v; for(int i = 0; i < 5; i++) { v.append(i*i); } v.append(-1); v.sort(); cout << "v = " << v << "\n"; cout << v.sum1() << "\n"; cout << v.sum2() << "\n"; cout << v.sum3() << "\n"; } // main