Hi,

I am trying to design a vector within a vector within a vector. For example, a school has 3 floors, each floor has 5 classrooms, each classroom has 20 students, each student has a last name and a first name. I know how to create a vector for floors and classrooms. I am having a hard time how it works with the student's names. How do I assign peter pan to floor 2, room3, for example?

Thanks for helping!

///floor 1
v[1]:[[classroom1][student1], [classroom2][student2], [classroom3][student3], [classroom3][student3]....]

`#include <iostream>
#include <fstream>
#include <string>
#include <vector>

using namespace std;

///*********************************************
///
/// Student Class
///
///*********************************************
class Student
{
private:
    string lastName;
    string firstName;
public:
    /// default constructor
    Student() {}
    /// default destructor
    ~Student() {}
    /// getter functions
    string getLastName() const { return lastName; }
    string getFirstName() const { return firstName; }
    /// setter functions
    void setLastName(string ln) { lastName = ln; }
    void setFirstName(string fn) { firstName = fn; }
};

///*********************************************
///
/// School Class (base class)
///
///*********************************************
class School
{
protected:
    Student student;
    vector< vector<int> > classRooms;
public:
    /// constructor
    School(int floor, int rooms, Student& s)
    {
        /// set number of floors and rooms, init students' name to empty string
        classRooms.resize(floor, vector<int>(rooms, 0));
        /// 
        classRooms.resize(floor, vector<Student>(????));
    }
};

/// main program
int main()
{
    /// some function that changes student's first and last names.
}`

Edited 2 Years Ago by newbiewwcode

You need another class. You should have a school class that has a vector of classrooms. The classroom class should hold on to what floor and room number it is. It should also have a vector of students that will hold all of the students that are in that classroom.

Thanks for the reply. Can you give me some examples on how to create a vector<Student> class?
would it be something like this

classRooms.resize(floor, vector<int>(rooms, vector<Student>(20, ????));

but how would you initialize the first and last name of the student?

This is how I would structure the code. If you are going to use OO principles then use them fully.

class Student
{
private:
    string lastName;
    string firstName;
public:
    /// default constructor
    Student() {}
    /// default destructor
    ~Student() {}
    /// getter functions
    string getLastName() const { return lastName; }
    string getFirstName() const { return firstName; }
    /// setter functions
    void setLastName(string ln) { lastName = ln; }
    void setFirstName(string fn) { firstName = fn; }
};

Then you need a classroom that will hold on to the students and where the classroom is located. The classroom should have functions to add and remove a student and also a way to acess the vector so you can get a list of all of the students in the class room. You will need your standard setters and getters as well. I'll leve that for you to code.

class ClassRoom
{
private:
    int floor;
    int roomNumber
    vector<Student> students;
public:
    //...
};

Then your school class will hold a 2D vector of of classrooms.

class School
{
private:
    int floors;
    int rooms;
    vector<vector<ClassRoom>> classRooms;
public:
    /// constructor
    School(int _floors, _int rooms, int seats)
    {
        floors = _floors;
        rooms = _rooms;
        // make the floors
        classRooms.resize(floors);
        // step through each floor and set the rooms
        for (int i = 0; i < floors; i++)
        {
            classRooms[i].resize(rooms);
        }
        // step through each classroom and set the room and floor
        for (int i = 0; i < floors; i++)
        {
            for (int j = 0; j < floors; j++)
            {
                classRooms[i][j].setFloor(i+1);
                classRooms[i][j].setRoom(i+1);
            }
        }
    }
};

After you get all of that you need a way to put a student into a classroom. to that you would have an add student function in the school class and it would look something like this

void School::AddStudent(int floor, int room, Student student)
{
    // -1 if you want floor and room to start at 1 instead of 0
    classRooms[floor - 1][room - 1].push_back(student);
}

Or ... a very simple way to start could be like this ...
(that lets readily you use all the STL vector member functions)

// schools.cpp //

#include <iostream>
#include <string>
#include <vector>

using namespace std;


struct Student
{
    string lname, fname;
} ;


ostream& operator << ( ostream& os, const Student& st )
{
    return os << st.lname << ", " << st.fname;
}


int main()
{
    // 'construct' school vs to have 3 floors
    vector < vector < vector < Student > > > vs ( 3 );

    // make each floor to have 5 classes
    for( int i = 0; i < 3; ++ i )
        vs[i].resize(5);

    // reserve room in each class for 20 students
    for( int i = 0; i < 3; ++ i )
    {
        for( int j = 0; j < 5; ++ j )
        vs[i][j].reserve(20);
    }

    // assign peter pan to floor 2, room3, seat 1
    Student tmp;
    tmp.lname = "Pan", tmp.fname = "Peter";
    vs[1][2].push_back(tmp);

    Student add[] =
    {
        {"Mary", "Jane"},
        {"Billy", "Bob"},
        {"Peggey", "Sue"}
    };

    int size = sizeof add / sizeof(Student);

    cout << "There are " << size << " students being added ...\n";

    for( int i = 0; i < size; ++ i )
         vs[1][2].push_back( add[i] );

    // show class vs[1][2] ...
    cout << "Class now has ... \n";
    for( size_t i = 0; i < vs[1][2].size(); ++i )
         cout << vs[1][2][i] << endl;
}

Edited 2 Years Ago by David W

You could use nested classes so that each instance of school will have it's own instances of the required classes. This also has the advantage of naming each section of the vectors that you need:

The header:

#include <vector>
#include <string>

using std::vector;
using std::string;
class School
{
private:
    class Student
    {
        friend class Classroom;
    public:
        string name;
        vector<Classroom> schedule;
    };
    class Classroom
    {
    public:
        Classroom();
        ~Classroom();
        vector<Student> students;
        string teacher;
        string subject;
    };
    class Floor
    {
    public:
        vector<Classroom> classrooms;
    };
    vector<Floor> floors;        
public:
    School();
    School(int num_of_floors, int rooms_per_floor, int students_per_room);
    ~School();
};

The School constructor would look something like this:

School::School(int num_of_floors, int rooms_per_floor, int students_per_room)
{
    floors.resize(num_of_floors);
    for (Floor f : floors)
    {
        f.classrooms.resize(rooms_per_floor);
        for (Classroom c : f.classrooms)
        {
            c.students.resize(students_per_room);
        }
    }
}

Notice how each vector nest is named so that classroom 3 of floor 2 would be floors[1].classrooms[2].
Also once you've resized the vectors you can set the properties of each element using the index, which gives you more control over using push_back.

Edited 2 Years Ago by tinstaafl

Thanks, tinstaafl. Your answer is truly brilliant. Wish I could've thought of that.

This question has already been answered. Start a new discussion instead.