Topical Information

The purpose of this quiz is to give you a chance to practice the topics involved with nD vector structures in C++.

Question Set Information

Questions

  1.  
    TRUE  FALSE  A vector that consists of strings is actually 3-dimensional.
    TRUE  FALSE  A vector structure used to represent the consistency inside a block of cheese will be 2D.
    TRUE  FALSE  Heat flow around the surface of a box would be most compactly stored as a 3D vector.
  2. Describe the best way to store heat flow information for the surface of a hollow box.

    
    This requires graphics to handle and we all know I can't draw.  But I'm going
    to do my best to describe the situation for you...
    
    First, think of storing heat-flow information if the box were represented in a
    3D structure.  The entire inside of the box would be wasted space as the air
    would act as an insulator and not conduct properly.  This represents
    (h-1)(w-1)(l-1) wasted space — all but the surface entries are unused in
    our process.
    
    Now take the hollow box and unfold it.  The result is a lower-case T,
    typically.  Now circumscribe a rectangle around this flattened out surface.
    There are parts of this rectangle that represent the box' surface and other
    parts I'll call holes.
    
    The holes in the rectangle are themselves rectangular and represent wasted
    storage on the order of 2h(h+w)+2h^2=4h^2+2hw=2h(2h+w).
    
    Depending on the magnitude of l vs. h, this is probably smaller.  But is it
    the smallest we can get?
    
    Now take the individual sides of the box apart.  There are 2 hl's, 2 hw's, and
    2 lw's.  Place them in a flat stack.  This is now a 3D structure again, but of
    depth only 6 and having much less wasted space than the original 3D structure.
    But how does it compare to the 2D mapping we came up with before?
    
    Let's make the simplifying assumption that w<l and w<h.  Then when we
    measure holes we get
    2h(l-w)+2l(h-w)=2hl-2hw+2hl-2lw=4hl-2hw-2lw=2(2hl-(h+l)w).  This is harder to
    call, but we could easily run some numbers in Mathematica to check.  I'd say
    that, in general, this one will be smaller, though.
    
    
  3. Given a multi-dimensional vector structure declared as 'vector< vector<double> > mat', answer each of the following:

    1. the structure contains mat.size()*mat[0].size() elements (how many? this may be formulaic...)
    2.  
      TRUE  FALSE  mat[2][4] represents the 5th element in the 3rd row
    3.  
      TRUE  FALSE  mat[2] represents the entire 3rd row
    4.  
      TRUE  FALSE  mat represents the entire vector structure
    5.  
      TRUE  FALSE  mat[][4] represents the entire 5th column
    6. the data type of mat[2][4] is double
    7. the data type of mat[2] is vector<double>
    8. the data type of mat is vector< vector<double> >
  4. For each dimension an nD vector structure has, we need (at least) n loop(s) to process it. During the entry of data elements, this is often a indefinite style loop (since we don't know yet how many items there are). Once data is entered and we are processing the elements, the loop used is typically a definite/for loop.

  5. If you plan to use a 2D vector structure whose base element type is long integer, show a set of typedefinitions which would prove useful to simplify the program's declarations and argument types.

    
    typedef vector<long> LVec1D;
    typedef LVec1D::size_type  LVec1D_sz;
    typedef vector<LVec> LVec2D;
    typedef LVec2D::size_type  LVec2D_sz;
    
    The size_type typedefs may be left off, of course, but the vector ones are
    musts.
    
    
  6. Use the above typedefinitions to code a function that will search an entire 2D vector structure of long integers to find the smallest value amongst the data. You should take the vector structure as input to the function and return both the smallest value and the integral position (row and column) of the smallest value.

    
    inline long smallest(const LVec1D & vec, LVec1D_sz & sm_pos)
    {
        long min = vec[0];
        sm_pos = 0;
        for (LVec1D_sz at = 1; at != vec.size(); ++at)
        {
            if (vec[at] < min)
            {
                min = vec[at];
                sm_pos = at;
            }
        }
        return min;
    }
    
        inline
    long smallest(const LVec2D & vec, LVec2D_sz & sm_row, LVec1D_sz & sm_col)
    {
        long min = vec[0][0];
        sm_row = 0;
        sm_col = 0;
        for (LVec2D_sz row = 0; row != vec.size(); ++row)
        {
            LVec1D_sz min_on_row;
            long row_min = smallest(vec[row], min_on_row);
            if (row_min < min)
            {
                min = row_min;
                sm_row = row;
                sm_col = min_on_row;
            }
        }
        return min;
    }
    
    

    Overload this function with an inlined companion that will only return the smallest value and not its coordinates within the structure.

    
    inline long smallest(const LVec2D & vec)
    {
        LVec2D_sz r;
        LVec1D_sz c;
        return smallest(vec, r, c);
    }
    
    
  7. Write a function that will accept a 2D vector structure containing short integers and return a vector containing the average of the elements along each row of the input 2D structure.

        inline
    void row_avg(const vector<vector<short> > & data,
                 vector<double> & avgs)
    {
        avgs.clear();
        for (vector<vector<short> >::size_type r = 0; r != data.size(); ++r)
        {
            double s = 0.0;
            for (vector<short>::size_type c = 0; c != data[r].size(); ++c)
            {
                s += data[r][c];
            }
            avgs.push_back(s/data[r].size());
        }
        return;
    }
    
    

    Write a similar function to return a vector containing the averages of each column of a 2D structure of short integers given by the caller.

    
        inline
    void col_avg(const vector<vector<short> > & data,
                 vector<double> & avgs)
    {
        avgs.clear();
        for (vector<short>::size_type c = 0; c != data[0].size(); ++c)
        {
            double s = 0.0;
            for (vector<vector<short> >::size_type r = 0; r != data.size(); ++r)
            {
                s += data[r][c];
            }
            avgs.push_back(s/data.size());
        }
        return;
    }
    
    

    Can these two functions be overloads of one another? Why/Why not?

    
    No.  They have identical argument lists.
    
    
  8. Show how to create a set of parallel vector [structures] that can contain the following: grades for each student on all course assignments throughout the semester, names for each student, titles for each assignment, and weighting factors for each assignment.

    Give declarations for all of your variables and show a drawing of how the vectors align in parallel.

    
    vector<vector<double> > grades;
    vector<double> weights;
    vector<string> names, titles;
    
    
          titles          weights     grades
        +========+       +=======+       +=====+=====+=====+=====+=====+
        |        |       |       |       |     |     |     |     |     |
        +========+       +=======+       +=====+=====+=====+=====+=====+
        |        | <-i-> |       | <-i-> |     |     |     |     |     |
        +========+       +=======+       +=====+=====+=====+=====+=====+
        |        |       |       |       |     |     |     |     |     |
        +========+       +=======+       +=====+=====+=====+=====+=====+
        |        |       |       |       |     |     |     |     |     |
        +========+       +=======+       +=====+=====+=====+=====+=====+
    
                                                 /\
                                                 ||
                                                 m
                                                 ||
                                                 \/
    
                                      n  +-----+-----+-----+-----+------+
                                      a  |     |     |     |     |      |
                                      m  |     |     |     |     |      |
                                      e  |     |     |     |     |      |
                                      s  +-----+-----+-----+-----+------+
    
    
  9.  
    TRUE  FALSE  1D (one dimension) can represent either a row or a column of data.
    TRUE  FALSE  2D represents rows-by-columns — never the other way around.
    TRUE  FALSE  3D can represent planes of rows of elements (columns).
    TRUE  FALSE  The dimensions represented in a multi-dimensional vector structure can be physical, temporal, or even just by definition/societal convention.
  10. Describe an nD vector structure to represent all the books in a particular row at the library — content and all.

    
    A vector of strings could represent a page of text.  A vector of these could
    represent a chapter.  A vector of chapters would represent a book.  A vector
    of books would represent a shelf.  A vector of shelves would represent a rack.
    And a vector of racks would represent a row/aisle in a library.
    
    

    How many dimensions is your structure? How can you tell? (Hint: How many dimensions is just a single page from a single book?)

    
    7 dimensional.  Each vector and string represents a dimension.
    
    

    Show typedefinitions for your structure. (You can skip the position/size types — just the typedefinitions for the data.)

    
    typedef string Line;
    typedef vector<Line> Page;
    typedef vector<Page> Chapter;
    typedef vector<Chapter> Book;
    typedef vector<Book> Shelf;
    typedef vector<Shelf> Rack;
    typedef vector<Rack> Row;