1.
|
True False
|
|
C++ uses a special internal mechanism to
allow the use of << and >> with streams; it is not possible for a
programmer to use this mechanism with other classes.
|
2.
|
True False
|
|
A precondition on a function can document
what inputs are legal to a function, but it can't prevent the program from
attempting to call the function with illegal inputs.
|
3.
|
True False
|
|
Given an arbitrary binary tree, a postorder
traversal of that tree will visit the nodes in the exact reverse order
of a preorder traversal.
|
4.
|
True False
|
|
For a stack, "push" and "pop" cancel each
other out: a push of any value followed by a pop leaves the stack in exactly
the state it was in initially.
|
5.
|
True False
|
|
For a queue, "enqueue" and "dequeue" cancel
each other out: an enqueue of any value followed by a dequeue leaves the
queue in exactly the state it was in initially.
|
6.
|
True False
|
|
The "new" operator in C++ returns a fresh,
statically-allocated instance of a class.
|
7.
|
True False
|
|
If a function f(n) is always less than another
function g(n), then f(n) = O(g(n))
|
8.
|
True False
|
Different binary search trees can have the
same inorder traversal.
|
|
9.
|
True False
|
Although binary searching a sorted array
has logarithmic runtime on average, it can take as much as linear time
in the worst case.
|
|
10.
|
True False
|
If a class overloads the + operator, the
compiler will check that the associated function really does perform an
addition-like operation.
|
|
11.
|
True False
|
Every binary tree with more than three nodes
must have an interior node that is not the root.
|
|
12.
|
True False
|
C++ references are a purely syntactic convenience
that do not make the language inherently more powerful than C.
|
|
13.
|
True False
|
Since a derived class does not have access
to its base class's private data, instances of the derived class do not
set aside space for the base class's data members.
|
|
14.
|
True False
|
The C++ inheritance mechanism allows us to
rewrite any recursive function non-recursively.
|
|
15.
|
True False
|
Activation records are allocated in a special
region of memory that is managed automatically by the language.
|
|
16.
|
True False
|
According to the definition of the Set ADT,
if I have a set of 10 integers, and I add an integer to the set, I will
always end up with a set of 11 integers.
|
|
17.
|
True False
|
assert( false ) at any point in
a program will cause that program to immediately abort.
|
|
18.
|
True False
|
It is impossible to write a binary search
function for a sorted linked list of integers that runs in O(log
n) time for a list of length n.
|
|
19.
|
True False
|
The this pointer is a global variable
in C++ programs that points to a single, statically-allocated object.
|
|
20.
|
True False
|
The bool type with the values true
and false, and the int type with the values 1 and 0 can
both be used to represent boolean values, but 1 and 0 should be used when
possible because it makes the program faster.
|
[12] Question 2:
Here is a C++ function that implements a new kind of searching algorithm:
int deluxeSearch( int data[], int size, int item )
{
return deluxeSearchInRange( data, item, 0, size - 1 );
}int deluxeSearchInRange( int data[], int item, int lo, int hi )
{
if( lo hi ) {
return -1;
}
int mid1 = lo + (hi-lo)/3;
int mid2 = lo + 2 * (hi - lo)/3;
if( item < data[ mid1 ] ) {Answer the following questions:
return deluxeSearchInRange( data, item, lo, mid1 - 1 );
} else if( item == data[ mid1 ] ) {
return mid1;
} else if( item data[ mid1 ] && item < data[ mid2 ] ) {
return deluxeSearchInRange( data, item, mid1 + 1, mid2 - 1 );
} else if( item == data[ mid2 ] ) {
return mid2;
} else {
return deluxeSearchInRange( data, item, mid2 + 1, hi );
}
}
Give two questions that you would like to ask about the specification
of this ADT before you start programming. For each question, write
a sentence or two explaining why the answer to this question would affect
your approach to the task
[14] Question 4:
Here is a portion of a program:
#include <iostream.h>class Simple
{
public:
virtual int goAhead();
};
int Simple::goAhead() {
return 17;
}
int main( void )This is obviously not a complete program, because it's missing at least the definition of the function getSimpleObject(). Surprisingly, when I compile and run the whole program, it prints out not 17, but 51! It's possible to finish writing this program in such a way that it prints out 51. Provide the rest of the program so that this happens. You may not modify the code that's already written down; you should instead add a definition for the getSimpleObject function (and probably add some other code too). You are also not permitted to make any use of cout in the code you add. (Hint: what kind of method is goAhead)?
{
Simple *obj = getSimpleObject();
cout << (obj-goAhead()) << endl;
return 0;
}
[10] Question 5:
Suppose you are given the following definition of a Dir type:
for( int idx = 0; idx < 10; ++idx ) {
Dir sneakyDir = (Dir)(idx);
printDir( sneakyDir
);
}
Choose a graceful method of error handling for printDir so
that this malicious code doesn't cause unpredictable behaviour in the program.
How would you rewrite printDir to use this error handling mechanism?
To store movie ratings, you decide to create a table-style ADT called
MovieDict. An instance of the MovieDict ADT should be
able to record votes, return the ratings for movies by name, and provide
the name of the highest-rated movie. Although the final version of
the program will be used from a WWW turnin-like form, you are provided
with the following sample client program to get an idea of how MovieDict
will be used:
#include "moviedict.h"
int main( void )
{
MovieDict dict;
dict.vote( "Citizen Kane", 9 ); // Bob votes 9 on "Citizen Kane"
dict.vote( "The Avengers", 1 ); // Fred votes 1 on "The Avengers"
dict.vote( "Citizen Kane", 10 ); // Fred votes 10 on "Citizen Kane"
dict.vote( "Fargo", 10 ); // Alice votes 10 on "Fargo"
// Prints out 1.0, the average of all votes for "The Avengers"
cout << dict.getRating( "The Avengers" ) << endl;
// Prints out 9.5, the average of all votes for "Citizen Kane"
cout << dict.getRating( "Citizen Kane" ) << endl;
char buf[ 100 ];
// Copies "Fargo" into the buffer buf, because it has
// the highest overall rating, 10.
dict.findBest( buf );
cout << "The movie to bet on is " << buf << "." << endl;
return 0;You've already completed some of the design of the ADT. You've decided to use a linked-list representation to store the dictionary entries. You've even created a declaration for a Node struct (that goes into the header file "moviedict.h"), which the ADT will use to store information for each movie:
}
#ifndef __MOVIEDICT_H__
#define __MOVIEDICT_H__
struct Node
{
char name[ MAX_NAME_LENGTH ]; // The name of
this movie
int sum_of_votes; // The sum of all votes cast
so far
int number_of_votes; // The number of votes
cast, needed
// to compute the average
Node *next; // Linked-list pointer
};
#endif // __MOVIEDICT_H__
MovieDict m1;
m1.vote( "Pi the Movie", 9 );
// ... other stuff here
MovieDict m2 = m1;
What potential dynamic memory problem can arise by doing this assignment?
[4] Bonus Question 1:
Give at least four of the metasyntactic variable names mentioned in
lecture this quarter.
[10] Bonus Question 2:
Suppose that we redefine the nodes we use in binary search trees as
follows:
struct FancyNodeIn this representation, every node points to its left and right children, and also to its immediate parent (through the parent pointer). It turns out that given a pointer to a FancyNode which is the root of a binary search tree, it's possible to do an inorder traversal of the tree with O(1) additional space (that is, the amount of extra memory you use is constant: no recursion, no stacks, no extra dynamic memory of any kind!) Write a function cheapInOrder( FancyNode *root ) that does this.
{
int data;FancyNode *parent;
FancyNode *left;
FancyNode *right;
};