0

How everyone, I have a problem that's rather ambiguous. I think it's ambiguous in the sense that it is given by my instructor as it is without further explanation. I have created a simple vector class that stimulates vectors. On this basis, I am to further refine and add in new functionalities. According to my instructor: Use a simple vector you created before to create two other more complex vectors with

1) Memory allocation that doubles the size of memory when end reached, and 1/2's memory when the size reaches 1/4.

2) Implemented with a singularly linked list.

That's literally all I have to begin with. I am fairly new to coding. On this note, I am having a hard time approaching this problem, either because the instruction is insufficient, or I haven't gotten familiar enough with c++. Could someone pls give me some pointers on how to approach this problem? (What the hell am I supposed to do?) Any suggestions are greatly appreciated:)

Here's the vector class that I created:

SimpleVector.h:

#ifndef SIMPLEVECTOR_H
#define SIMPLEVECTOR_H
#include <iostream>
#include <new>       // Needed for bad_alloc exception
#include <cstdlib>   // Needed for the exit function
using namespace std;

template <class T>
class SimpleVector
{
private:
   T *aptr;          // To point to the allocated array
   int arraySize;    // Number of elements in the array
   void memError();  // Handles memory allocation errors
   void subError();  // Handles subscripts out of range

public:
   // Default constructor
   SimpleVector()
      { aptr = 0; arraySize = 0;}

   // Constructor declaration
   SimpleVector(int);

   // Copy constructor declaration
   SimpleVector(const SimpleVector &);

   // Destructor declaration
   ~SimpleVector();

   // Accessor to return the array size
   int size() const
      { return arraySize; }

   // Accessor to return a specific element
   T getElementAt(int position);

   // Overloaded [] operator declaration
   T &operator[](const int &);

   void push_back(T);

   T pop_back();

   void push_front(T);

   T pop_front();
};

//***********************************************************
// Constructor for SimpleVector class. Sets the size of the *
// array and allocates memory for it.                       *
//***********************************************************

template <class T>
SimpleVector<T>::SimpleVector(int s)
{
   arraySize = s;
   // Allocate memory for the array.
   try
   {
      aptr = new T [s];
   }
   catch (bad_alloc)
   {
      memError();
   }

   // Initialize the array.
   for (int count = 0; count < arraySize; count++)
      *(aptr + count) = 0;
}

//*******************************************
// Copy Constructor for SimpleVector class. *
//*******************************************

template <class T>
SimpleVector<T>::SimpleVector(const SimpleVector &obj)
{
   // Copy the array size.
   arraySize = obj.arraySize;

   // Allocate memory for the array.
   aptr = new T [arraySize];
   if (aptr == 0)
      memError();

   // Copy the elements of obj's array.
   for(int count = 0; count < arraySize; count++)
      *(aptr + count) = *(obj.aptr + count);
}

//**************************************
// Destructor for SimpleVector class.  *
//**************************************

template <class T>
SimpleVector<T>::~SimpleVector()
{
   if (arraySize > 0)
      delete [] aptr;
}

//*******************************************************
// memError function. Displays an error message and     *
// terminates the program when memory allocation fails. *
//*******************************************************

template <class T>
void SimpleVector<T>::memError()
{
   cout << "ERROR:Cannot allocate memory.\n";
   exit(EXIT_FAILURE);
}

//***********************************************************
// subError function. Displays an error message and         *
// terminates the program when a subscript is out of range. *
//***********************************************************

template <class T>
void SimpleVector<T>::subError()
{
   cout << "ERROR: Subscript out of range.\n";
   exit(EXIT_FAILURE);
}

//*******************************************************
// getElementAt function. The argument is a subscript.  *
// This function returns the value stored at the sub-   *
// cript in the array.                                  *
//*******************************************************

template <class T>
T SimpleVector<T>::getElementAt(int sub)
{
   if (sub < 0 || sub >= arraySize)
      subError();
   return aptr[sub];
}

//*******************************************************
// Overloaded [] operator. The argument is a subscript. *
// This function returns a reference to the element     *
// in the array indexed by the subscript.               *
//*******************************************************

template <class T>
T &SimpleVector<T>::operator[](const int &sub)
{
   if (sub < 0 || sub >= arraySize)
      subError();
   return aptr[sub];
}

template <class T>
void SimpleVector<T>::push_front(T val){
   // Allocate memory for the array.
   try {
        T *new_Aptr = new T[arraySize + 1];

        for (int i = 0; i < arraySize; i++) {
            new_Aptr[i + 1] = aptr[i];
        }

        arraySize++;

        delete[] aptr;

        aptr = new_Aptr;

        aptr[0] = val;
    }
    catch(bad_alloc) {
        memError();
    }
}

template <class T>
void SimpleVector<T>::push_back(T val){
    try {
        T *new_Aptr = new T[arraySize + 1];

        for (int i = 0; i < arraySize; i++) {
            new_Aptr[i] = aptr[i];
        }

        delete[] aptr;

        aptr = new_Aptr;

        aptr[arraySize] = val;

        arraySize++;
    }
    catch(bad_alloc) {
        memError();
    }
}

template <class T>
T SimpleVector<T>::pop_front(){
   T dummy;
    try {
        T *new_Aptr = new T[arraySize - 1];

        arraySize--;

        for (int i = 0; i < arraySize; i++) {
            new_Aptr[i] = aptr[i + 1];
        }

        delete[] aptr;

        aptr = new_Aptr;

        return dummy;
    }
    catch(bad_alloc) {
        memError();
    }

}

template <class T>
T SimpleVector<T>::pop_back(){
    T dummy;
    try {
        T *new_Aptr = new T[arraySize - 1];

        arraySize--;

        for (int i = 0; i < arraySize; i++) {
            new_Aptr[i] = aptr[i];
        }

        delete[] aptr;

        aptr = new_Aptr;    

        return dummy; 
    }
    catch(bad_alloc) {
        memError();
    }
}
#endif

And here's the main class provided by my instructor.

main.cpp:
#include "SimpleVector.h"
void fillVec(SimpleVector<int> &);
void addVec(SimpleVector<int> &);
void delVec(SimpleVector<int> &);
void prntVec(SimpleVector<int> &,int);

//Execution Begins Here!
int main(int argc, char** argv) {
    //Declare Variables
    int size;

    //Read in the size
    cout<<"What size vector to test?"<<endl;
    cin>>size;
    SimpleVector<int> sv(size);

    //Initialize or input i.e. set variable values
    fillVec(sv);

    //Display the outputs
    prntVec(sv,10);

    //Add and subtract from the vector
    addVec(sv);

    //Display the outputs
    prntVec(sv,10);

    //Add and subtract from the vector
    delVec(sv);

    //Display the outputs
    prntVec(sv,10);

    //Exit stage right or left!
    return 0;
}

void addVec(SimpleVector<int> &sv){
    int add=sv.size()*0.1;
    for(int i=1;i<=add;i++){
        sv.push_front(i+add-1);
        sv.push_back(i-add);
    }
}

void delVec(SimpleVector<int> &sv){
    int del=sv.size()*0.2;
    for(int i=1;i<=del;i++){
        sv.pop_front();
        sv.pop_back();
    }
}

void fillVec(SimpleVector<int> &sv){
    for(int i=0;i<sv.size();i++){
        sv[i]=i%10;
    }
}
void prntVec(SimpleVector<int> &sv,int n){
    cout<<endl;
    for(int i=0;i<sv.size();i++){
        cout<<sv[i]<<" ";
        if(i%n==(n-1))cout<<endl;
    }
    cout<<endl;
}

I have some leeway with main.cpp(as it is kind of sketchy). More importantly, I need to know where to start with the instructions given. Thank you!!

V.Reeve
  • 53
  • 6
  • Start simple. Build the vector to double and ignore the other two for now. Once you get the doubling working, and you've tested it to prove that it works, then start working on the halving. The linked list... Use `std::list` if you can. If not, and you've never written a linked list before, get ready for some nastiness. Separate the linked list from everything else. Draw lots of pictures to help you visualize all of the operations. Spend some time getting a grip on pointers to pointers because they make linked lists [a lot easier to write](https://stackoverflow.com/a/22122095/4581301). – user4581301 Apr 08 '19 at 04:27
  • `std::forward_list`, on `std::list`. Sorry. – user4581301 Apr 08 '19 at 04:35

1 Answers1

0

I'm not 100% sure that this is what your professor is asking for, but from what I can gather, for part 1, you are supposed to change your vector class so that it only allocates memory when you reach the end of the vector or reach 1/4 of the memory size.

In your push_front function for example, you allocate new memory every time you add a single value to the vector. Instead, you should only allocate memory when you reach your memory size and double it instead of adding 1. Likewise, when removing a value from your array, you don't delete the memory until your vector size is 1/4 of the allocated memory.

For the second part of the question, I would recommend creating a second Node class that holds data and a pointer to another Node. In your vector class you would then have a pointer to the first Node in the list. Since this is a singly-linked list, to find your value, you can iterate through the list a certain number of times or until the next pointer is NULL.

From your question, it seems as though you just wanted a jumping off point for an assignment, so hopefully the above is helpful.

yuankhan
  • 3
  • 4