Question

In: Computer Science

C++ You are going to implement your own vector class. Actually, we are using the following...

C++ You are going to implement your own vector class. Actually, we are using the following small and simplified subset of the interface from std::vector to keep things manageable:

template class DiyVector{
    public:
        DiyVector();
        ~DiyVector();

        T& at(unsigned int index) const;
        // item at index
        // throws OutOfRange

        unsigned int size() const;
        // number of items in the vector

        void pushBack(const T& item);
        // append item at the end of vector

        void popBack();
        // remove item at the end of vector
        // throws OutOfRange

        void erase(unsigned int index);
        // remove element at index
        // throws OutOfRange

        void insert(unsigned int index, const T& item);
        // insert item before element at index, with:
        // 0 <= index <= size()
        // throws OutOfRange

        class OutOfRange{};

    private:

        // your implementation goes here!
};
Your DiyVector will store items of type T in an array that is dynamically allocated on the heap, using new[].

We only expand this array, but never shrink it:

when adding an item (using pushBack or insert), if there is no currently unused element in the array, create a new array, able to hold one more element, and copy over the old items. Of course, you delete[] the old, too-short array afterwards.

when deleting an item (using popBack or erase), you simply "pack" the array by copying all items behind the erased one to close the gap (and adjust the bookkeeping of used elements). Later, when a new item is to be added (using pushBack or insert), you re-use an old space at the end of the array, instead of creating a whole new array.

Your program must not use any item storage but arrays that are created by new[]. (No statically created arrays, no vectors, no other container classes from std::)

You deliver your DiyVector as a header file called diyvector.h.

It will be automatically tested by the following program( create a seperate file named vector-tester.cpp using code below) :

#include

#include "diyvector.h"

class TestFailed{

public:

TestFailed(int seq){

sequenceNumber = seq;

}

int sequenceNumber;

};

int testNumber = 0;

#define check(CALL) { testNumber++; if ( !(CALL) ) throw TestFailed(testNumber); }

#define checkException(CALL){ \

testNumber++; \

bool exceptionRaised = false; \

try{ \

CALL; \

}catch(DiyVector::OutOfRange& o){ \

exceptionRaised = true; \

} \

if ( !exceptionRaised ) throw TestFailed(testNumber); \

}

int main(){

try{

DiyVector v;

check(v.size() == 0); // test 1

checkException(v.at(0));

v.pushBack(42);

check(v.size() == 1);

check(v.at(0) == 42);

checkException(v.at(1)); // test 5

v.pushBack(43);

check(v.size() == 2);

check(v.at(1) == 43);

check(v.at(0) == 42);

v.popBack();

v.popBack();

check(v.size()==0);

checkException(v.popBack()); // test 10

v.pushBack(142);

v.pushBack(143);

v.pushBack(144);

check(v.size()==3);

check(v.at(0)==142);

check(v.at(1)==143);

check(v.at(2)==144);

checkException(v.at(3)); // test 15

v.at(0) = 17;

check(v.at(0)==17);

checkException(v.erase(3));

checkException(v.erase(42));

v.erase(1);

check(v.size()==2);

check(v.at(0)==17); // test 20

check(v.at(1)==144);

v.pushBack('A');

v.pushBack('B');

check(v.size()==4);

check(v.at(2)==65);

check(v.at(3)==66);

v.insert(2, 22);

check(v.at(0)==17); // test 25

check(v.at(1)==144);

check(v.at(2)==22);

check(v.at(3)==65);

check(v.at(4)==66);

check(v.size()==5); // test 30

DiyVector v2;

v2.insert(0,42);

v2.pushBack(11);

v2.insert(0,44);

check(v2.size()==3);

check(v2.at(0)==44);

check(v2.at(1)==42);

check(v2.at(2)==11);

v2.popBack();

v2.insert(0,99);

check(v2.size()==3); // test 35

check(v2.at(0)==99);

check(v2.at(1)==44);

check(v2.at(2)==42);

DiyVector v3;

v3.pushBack(1);

v3.erase(0);

checkException(v3.at(0));

check(v3.size()==0); // test 40

checkException(v3.insert(1,-5));

check(v3.size()==0); // test 42

std::cout << "All tests passed!\n";

}

catch(TestFailed& tf){

std::cerr << "Test number " << tf.sequenceNumber << " failed.\n";

return 1;

}

catch(...){

std::cerr << "an unexpected exception occured\n";

std::cerr << "Tests passed so far: " << testNumber << std::endl;

return 2;

}

return 0;

}

Solutions

Expert Solution

// diyvector.h

#ifndef DIYVECTOR_H_
#define DIYVECTOR_H_

template <class T>
class DiyVector
{
public:
DiyVector();
~DiyVector();

T& at(unsigned int index) const;
// item at index
// throws OutOfRange

unsigned int size() const;
// number of items in the vector

void pushBack(const T& item);
// append item at the end of vector

void popBack();
// remove item at the end of vector
// throws OutOfRange

void erase(unsigned int index);
// remove element at index
// throws OutOfRange

void insert(unsigned int index, const T& item);
// insert item before element at index, with:
// 0 <= index <= size()
// throws OutOfRange

class OutOfRange{};

private:
unsigned int numElements;
unsigned int maxSize;
T *arr;
};

/// default constructor to create an empty vector
template <class T>
DiyVector<T>::DiyVector()
{
   arr = nullptr; // set arr to nullptr
   numElements = 0; // set current number of elements to 0
   maxSize = 0; // set maximum size of arr to 0
}

// destructor to delete the release the memory of the vector
template <class T>
DiyVector<T>::~DiyVector()
{
   // if arr is not null, delete the pointer
   if(arr != nullptr)
       delete arr;
}

// item at index
// throws OutOfRange
template <class T>
T& DiyVector<T>::at(unsigned int index) const
{
   // if valid index, return the element at index
   if(index >=0 && index < numElements)
       return arr[index];
   else // else throw OutOfRange exception
       throw OutOfRange();
}

// number of items in the vector
template <class T>
unsigned int DiyVector<T>:: size() const
{
   return numElements;
}

// append item at the end of vector
template <class T>
void DiyVector<T>::pushBack(const T& item)
{
   // if arr is null or vector is full
   if(arr == nullptr || numElements == maxSize)
   {
       // expand the array
       maxSize = maxSize + 1;
       T *temp = new T[maxSize];
       for(int i=0;i<numElements;i++)
           temp[i] = arr[i];
       if(arr != nullptr)
           delete arr;
       arr = temp;
   }

   // add the item at the end
   arr[numElements] = item;
   numElements++; // increment the size of vector
}

// remove item at the end of vector
// throws OutOfRange
template <class T>
void DiyVector<T>:: popBack()
{
   // if empty vector, throw OutOfRange exception
   if(numElements == 0)
       throw OutOfRange();
   numElements--; //else decrement the number of items
}

// remove element at index
// throws OutOfRange
template <class T>
void DiyVector<T>:: erase(unsigned int index)
{
   // if valid index, then remove the element at index
   if(index >=0 && index < numElements)
   {
       // shift the elements to the left
       for(int i=index;i<numElements-1;i++)
       {
           arr[i] = arr[i+1];
       }
       numElements--; // decrement the number of elements
   }else // else throw OutOfRange exception
       throw OutOfRange();
}

// insert item before element at index, with:
// 0 <= index <= size()
// throws OutOfRange
template <class T>
void DiyVector<T>:: insert(unsigned int index, const T& item)
{
   // if valid index
   if(index >=0 && index <= numElements)
   {
       // if arr is null or vector is full, expand the vector
       if(arr == nullptr || numElements == maxSize)
       {
           maxSize = maxSize + 1;
           T *temp = new T[maxSize];
           for(int i=0;i<numElements;i++)
               temp[i] = arr[i];
           if(arr != nullptr)
               delete arr;
           arr = temp;
       }

       // loop to shift the elements to the right
       for(int i=numElements;i>index;i--)
       {
           arr[i] = arr[i-1];
       }
       // insert the element at the index
       arr[index] = item;
       numElements++;
    }else // else throw OutOfRange exception
       throw OutOfRange();
}


#endif
//end of diyvector.h

// vector-tester.cpp

#include <iostream>
#include "diyvector.h"
class TestFailed{
public:
TestFailed(int seq){
sequenceNumber = seq;
}
int sequenceNumber;
};
int testNumber = 0;
#define check(CALL) { testNumber++; if ( !(CALL) ) throw TestFailed(testNumber); }
#define checkException(CALL){ \
testNumber++; \
bool exceptionRaised = false; \
try{ \
CALL; \
}catch(DiyVector::OutOfRange& o){ \
exceptionRaised = true; \
} \
if ( !exceptionRaised ) throw TestFailed(testNumber); \
}
int main(){
try{
DiyVector v;
check(v.size() == 0); // test 1
checkException(v.at(0));
v.pushBack(42);
check(v.size() == 1);
check(v.at(0) == 42);
checkException(v.at(1)); // test 5
v.pushBack(43);
check(v.size() == 2);
check(v.at(1) == 43);
check(v.at(0) == 42);
v.popBack();
v.popBack();
check(v.size()==0);
checkException(v.popBack()); // test 10
v.pushBack(142);
v.pushBack(143);
v.pushBack(144);
check(v.size()==3);
check(v.at(0)==142);
check(v.at(1)==143);
check(v.at(2)==144);
checkException(v.at(3)); // test 15
v.at(0) = 17;
check(v.at(0)==17);
checkException(v.erase(3));
checkException(v.erase(42));
v.erase(1);
check(v.size()==2);
check(v.at(0)==17); // test 20
check(v.at(1)==144);
v.pushBack('A');
v.pushBack('B');
check(v.size()==4);
check(v.at(2)==65);
check(v.at(3)==66);
v.insert(2, 22);
check(v.at(0)==17); // test 25
check(v.at(1)==144);
check(v.at(2)==22);
check(v.at(3)==65);
check(v.at(4)==66);
check(v.size()==5); // test 30
DiyVector v2;
v2.insert(0,42);
v2.pushBack(11);
v2.insert(0,44);
check(v2.size()==3);
check(v2.at(0)==44);
check(v2.at(1)==42);
check(v2.at(2)==11);
v2.popBack();
v2.insert(0,99);
check(v2.size()==3); // test 35
check(v2.at(0)==99);
check(v2.at(1)==44);
check(v2.at(2)==42);
DiyVector v3;
v3.pushBack(1);
v3.erase(0);
checkException(v3.at(0));
check(v3.size()==0); // test 40
checkException(v3.insert(1,-5));
check(v3.size()==0); // test 42
std::cout << "All tests passed!\n";
}
catch(TestFailed& tf){
std::cerr << "Test number " << tf.sequenceNumber << " failed.\n";
return 1;
}
catch(...){
std::cerr << "an unexpected exception occured\n";
std::cerr << "Tests passed so far: " << testNumber << std::endl;
return 2;
}
return 0;
}
//end of vector-tester.cpp

Output:


Related Solutions

(Python or C++) We are going to implement the following scheduling algorithms that we discussed in...
(Python or C++) We are going to implement the following scheduling algorithms that we discussed in class: 1. First-Come First-Served (FCFS) 2. Shortest Remaining Time First (SRTF) 3. Highest Response Ratio Next (HRRN) 4. Round Robin, with different quantum values (RR) We are interested to compute the following metrics, for each experiment: _ The average turnaround time _ The total throughput (number of processes done per unit time) _ The CPU utilization _ The average number of processes in the...
in C++ For this program, you are going to implement a stack using an array and...
in C++ For this program, you are going to implement a stack using an array and dynamic memory allocation. A stack is a special type of data structure that takes in values (in our case integers) one at a time and processes them in a special order. Specifically, a stack is what's called a first-in-last-out (FILO) data structure. That is to say, the first integer inserted into the stack is the last value to be processed. The last value in...
Using the following code write the following instructions in C++ Implementation: 1. Re-implement your String class...
Using the following code write the following instructions in C++ Implementation: 1. Re-implement your String class to use a dynamically allocated array for storage. It will be a NULL terminating charater array. 2. This dynamic version of the String will only allocate exactly the amount of memory necessary to store the characters. That is, the length will be the same as the capacity. However, the size of the dynamic array needs to have an extra char for the NULL terminator....
Implement the minimum priority queue UnsortedMPQ (using vector) that is a child class of the provided...
Implement the minimum priority queue UnsortedMPQ (using vector) that is a child class of the provided MPQ class. The functions from MPQ that are virtual function (remove min(), is empty(), min(), and insert()) must be implemented in the child classes. The functions remove min() and min() should throw an exception if the minimum priority queue is empty. For the UnsortedMPQ class, you will use a vector to implement the minimum priority queue functions. The insert() function should be O(1) and...
C++ question: Design and implement your own linked list class to hold a sorted list of...
C++ question: Design and implement your own linked list class to hold a sorted list of integers in ascending order. The class should have member functions for inserting an item in the list, deleting an item from the list, and searching the list for an item. Note: the search function should return the position of the item in the list (first item at position 0) and -1 if not found. In addition, it should have member functions to display the...
Using STL stack class, implement in C++ the following pseudocodefunctioncheckBraces(aString: string) that checks for...
Using STL stack class, implement in C++ the following pseudocode functioncheckBraces(aString: string) that checks for balanced braces { } in a given string /arithmetic expressions. Write a main() program to test the function.// Checks the string aString to verify that braces match.// Returns true if aString contains matching braces, false otherwise.checkBraces(aString: string): boolean{aStack = a new empty stackbalancedSoFar = truei =0// Tracks character position in stringwhile (balancedSoFar and i < length of aString) {ch = character at position i in...
Write a C++ class that implement two stacks using a single C++ array. That is, it...
Write a C++ class that implement two stacks using a single C++ array. That is, it should have functions pop_first(), pop_second(), push_first(…), push_second(…), size_first(), size_second(), …. When out of space, double the size of the array (similarly to what vector is doing). Notes: Complete all the functions in exercise_2.cpp, then submit this cpp file. pop_first() and pop_second() should throw std::out_of_range exception when stack is empty. CODE: #include <cstdio> #include <stdexcept> template <class T> class TwoStacks { public:   // Constructor, initialize...
in C++ We are going to implement the following scheduling algorithms 1. First-Come First-Served (FCFS) 2....
in C++ We are going to implement the following scheduling algorithms 1. First-Come First-Served (FCFS) 2. Shortest Remaining Time First (SRTF) 3. Highest Response Ratio Next (HRRN) 4. Round Robin, with di_erent quantum values (RR) We are interested to compute the following metrics, for each experiment: _ The average turnaround time _ The total throughput (number of processes done per unit time) _ The CPU utilization _ The average number of processes in the ready queue The simulator needs to...
C++ coding functions Implement the following class using linked lists. Creating a simple linked list class...
C++ coding functions Implement the following class using linked lists. Creating a simple linked list class to use is probably your first step.(Please do not use collections like .push() . pop(), etc.) and instead create the implementation A templated stack class that stores type T with the following public functions: - void Push(T t) - adds t to the top of the stack - T Pop() - asserts that the stack is not empty then removes and returns the item...
C++ For this assignment, you will implement the MyString class. Like the string class in C++’s...
C++ For this assignment, you will implement the MyString class. Like the string class in C++’s standard library, this class uses C-strings as the underlying data structure. Recall that a C-string is a null-terminated array of type char. See section 8.1 in Savitch for more information about C-strings; in particular, you will find it helpful to take advantage of several of the C-string functions mentioned in that section. What To Do. In the hw8 directory that is created, you will...
ADVERTISEMENT
ADVERTISEMENT
ADVERTISEMENT