02. Log N Vector
Due Sunday by 11:59pm
Points 149
O(log(N)) Vector
std::vector is pretty cool but it has one big problem: every once in a while, push_back has to create a whole new array and copy a bunch of elements which is O(n)! Luckily, we can do better, in terms of Big-O. The goal of this homework is to write a class that behaves like a vector but without the O(n) push_back.
Whenever we run out of space, we'll still allocate an array that's twice as big as the last one but instead of copying all the old elements to it, we'll keep all the current elements where they are and store new ones in the new array until it's full. One way to implement this is to have an std::vector of arrays. If our vector is called "v", then v[0] is an array of size 1, v[1] would be an array of size 2, v[2] would have size 4, ..., v[x] would have a size of 2x.
Before you start writing code, figure out how to take an index into our data structure and convert it to the index in "v". For example, index 0 corresponds to v[0][0] and index 6 corresponds to v[2][3]. Feel free to talk to anyone, especially other students, for help with this part of the assignment!
Starter Code
log_n_vector.h
#ifndef _log_n_vector_h_ #define _log_n_vector_h_ #include <cmath> #include <memory> #include <vector> template <typename T> class LogNVector { // These member variables are suggested and not required! // Feel free to use change the variable names or types, as long as you // follow the spirit of the assignment. std::vector<std::unique_ptr<T[]> > arrays_; int size_, capacity_; public: LogNVector() { // TODO } LogNVector(const LogNVector& other) : LogNVector() { // TODO } LogNVector(std::initializer_list<T> ilist) : LogNVector() { // TODO } ~LogNVector() { // TODO } int size() const noexcept { // TODO } int capacity() const noexcept { // TODO } void push_back(const T& value) { // TODO } const T& operator[](int index) const { // TODO } T& operator[](int index) { // TODO } }; #endif // _log_n_vector_h_
manual_test.cpp
#include <iostream> #include "log_n_vector.h" using std::cout; using std::endl; int main() { LogNVector<int> v = {0, 11, 22, 33, 44, 55, 66, 77, 88, 99, 110, 121}; cout << "v[0] == " << v[0] << ", &v[0] == " << &v[0] << endl; for (int j = 1; j < v.size(); ++j) { // All the elements in the same array should have sequential addresses. // For example, &v[2] == &v[1] + 1 // However, there's no guarantee that &v[1] == &v[0] + 1. cout << "v[" << j << "] == " << v[j] << ", " << "&v[" << j << "] - &v[" << j - 1 << "] == " << &v[j] - &v[j - 1] << endl; } return 0; }
$ clang -pedantic -Wall -lm -lstdc++ -lpthread -std=c++14 -o example log_n_vector/manual_test.cpp $ ./example
v[0] == 0, &v[0] == 0xd57c20 v[1] == 11, &v[1] - &v[0] == 16 v[2] == 22, &v[2] - &v[1] == 1 v[3] == 33, &v[3] - &v[2] == -9 v[4] == 44, &v[4] - &v[3] == 1 v[5] == 55, &v[5] - &v[4] == 1 v[6] == 66, &v[6] - &v[5] == 1 v[7] == 77, &v[7] - &v[6] == 33 v[8] == 88, &v[8] - &v[7] == 1 v[9] == 99, &v[9] - &v[8] == 1 v[10] == 110, &v[10] - &v[9] == 1 v[11] == 121, &v[11] - &v[10] == 1
main.cpp
-------------------------------------------------------------------
#include <iostream>
#include "log_n_vector.h"
using std::cout;
using std::endl;
int main() {
LogNVector<int> v = {0, 11, 22, 33, 44,
55, 66, 77, 88, 99, 110, 121};
cout << "v[0] == " << v[0] <<
", &v[0] == " << &v[0] <<
endl;
for (int j = 1; j < v.size(); ++j) {
cout << "v["
<< j << "] == " << v[j] <<
", "
<< "&v[" << j << "] - &v[" << j - 1
<< "] == "
<< &v[j] - &v[j - 1] << endl;
}
return 0;
}
--------------------------------------------------------------------
log_n_vector.h
-----------------------------------
#ifndef _log_n_vector_h_
#define _log_n_vector_h_
#include <cmath>
#include <memory>
#include <vector>
template <typename T>
class LogNVector {
private:
std::vector<std::unique_ptr<T[]> >
arrays;
int size_;
int capacity_;
public:
LogNVector() {
this->size_ =
0;
this->capacity_ =
0;
}
LogNVector(const LogNVector& other) :
LogNVector() {
int size =
other.size();
for(int k = 0; k <
size; k++)
this->push_back(other[k]);
}
LogNVector(std::initializer_list<T>
ilist) : LogNVector() {
typename
std::initializer_list<T>::iterator iter;
for (iter =
ilist.begin(); iter != ilist.end(); iter++)
this->push_back(*iter);
}
~LogNVector() {
// Destructor not
necessary. Already handled by std::unique_ptr
/*int numArrays =
this->arrays.size() - 1;
while(numArrays >=
0)
{
this->arrays[numArrays].reset();
--numArrays;
}*/
}
public:
int size() const noexcept {
return
this->size_;
}
int capacity() const noexcept {
return
this->capacity_;
}
public:
void push_back(const T& value) {
if(this->size_ ==
this->capacity_)
this->createNextArray();
int lastArr =
this->getLastArrNum();
int arrNextLoc =
this->size_ - getConsecMaxArrSize(lastArr - 1);
this->arrays[lastArr][arrNextLoc] = value;
size_ += 1;
}
public:
const T& operator[](int index) const {
int arrNum = log2(index
+ 1);
int position = index -
getConsecMaxArrSize(arrNum - 1);
return
this->arrays[arrNum][position];
}
T& operator[](int index) {
int arrNum = log2(index
+ 1);
int position = index -
getConsecMaxArrSize(arrNum - 1);
return
this->arrays[arrNum][position];
}
private:
void createNextArray()
{
int nextSize =
getArrMaxSize( getLastArrNum() + 1 );
this->arrays.emplace_back(new T[nextSize]);
this->capacity_ +=
nextSize;
}
int getLastArrNum() const
{
return this->arrays.size() - 1;
//return
log2(capacity + 2) - 1;
}
int getArrMaxSize(int num) const
{
if(num < 0)
return 0;
return exp2(num);
}
int getConsecMaxArrSize(int num) const
{
int total = 0;
for (int k = 0; k <=
num; k++)
total += getArrMaxSize(k);
return total;
}
};
#endif
02. Log N Vector Due Sunday by 11:59pm Points 149 O(log(N)) Vector std::vector is pretty cool...
vector.h: #ifndef VECTOR_H #define VECTOR_H #include <algorithm> #include <iostream> #include <cassert> template <typename T> class Vector { public: Vector( int initsize = 0 ) : theSize( initsize ), theCapacity( initsize + SPARE_CAPACITY ) { objects = new T[ theCapacity ]; } Vector( const Vector & rhs ) : theSize( rhs.theSize), theCapacity( rhs.theCapacity ), objects( 0 ) { objects = new T[ theCapacity ]; for( int k = 0; k < theSize; ++k) objects[ k ] = rhs.objects[ k...
One dimensional array What this code print #include <iostream> using namespace std; int main () { const int SIZE = 7; int numbers [SIZE] = {1, 2, 4, 8): // Initialize first 4 elements cout << Here are the contents of the array:\n"; for (int index = 0; index < SIZE: index++} cout << numbers[index] << ; cout << endl; return 0; }
Example program #include <string> #include <iostream> #include <cmath> #include <vector> using namespace std; vector<int> factor(int n) { vector <int> v1; // Print the number of 2s that divide n while (n%2 == 0) { printf("%d ", 2); n = n/2; v1.push_back(2); } // n must be odd at this point. So we can skip // one element (Note i = i +2) for (int i = 3; i <=...
Hi, I have C++ programming problem here: Problem: Please modify your string type vector in for push_back() function as below: void push_back(string str) { // increase vector size by one // initialize the new element with str } In addition, the standard library vector doesn't provide push_front(). Implement push_front() for your vector. Test your code with the main function below. int main() { vector v1(3); cout<<"v1: "; v1.print(); // this should display -, -, - for...
#include <iostream> #include <vector> #include <iomanip> using namespace std; int main() { const int NUM_ITEMS = 8; vector <double> inverse(NUM_ITEMS); int j; double temp; for (int i = 0; i < NUM_ITEMS; i++) { inverse.at(i) = 1 / (i + 1.0); } cout << fixed << setprecision(2); cout << "Original vector..." << endl; for (int i = 0; i < NUM_ITEMS; i++) { cout << inverse.at(i) << " "; } cout << endl; cout << "Reversed vector..." << endl; for...
Implementing the vector class in the following code (It's C++, not Java). You just need to implement all these methods: PushFront, PopFront, At, Erase, Insert, Clear, Reserve, Copy, Assign, and Destroy, please do not add any new properties. You cannot use std:: functions, && (unless being used for "AND"), or pass by reference. Your solutions must conform to the Big O notations next to each method. In the following code, I am going to match the names that STL uses...
When running the program at the destructor an exception is being thrown. Can someone help me out? vararray.h: #ifndef VARARRAY_H_ #define VARARRAY_H_ class varArray { public: varArray(); // void constructor int arraySize() const { return size; } // returns the size of the array int check(double number); // returns index of element containg "number" or -1 if none void addNumber(double); // adds number to the array void removeNumber(double); // deletes the number from the array ...
A library maintains a collection of books. Books can be added to and deleted from and checked out and checked in to this collection. Title and author name identify a book. Each book object maintains a count of the number of copies available and the number of copies checked out. The number of copies must always be greater than or equal to zero. If the number of copies for a book goes to zero, it must be deleted from the...
10.18 LAB: Plant information (vector) Given a base Plant class and a derived Flower class, complete main() to create a vector called myGarden. The vector should be able to store objects that belong to the Plant class or the Flower class. Create a function called PrintVector(), that uses the PrintInfo() functions defined in the respective classes and prints each element in myGarden. The program should read plants or flowers from input (ending with -1), adding each Plant or Flower to...
Who could write the array.cpp file ? //main.cpp #include "array.hpp" #include <iostream> int main() { int n; std::cin >> n; array a(n); for (int i = 0; i < n; i++) { std::cin >> a.data()[i]; } std::cout << "array size:" << a.max_size() << std::endl; std::cout << "array front:" << a.front() << std::endl; std::cout << "array back:" << a.back() << std::endl; int* data = a.data(); std::cout << "array elements using data:" << std::endl; for (int i = 0; i < n;...