You are to write solutions to each of the problems given below. You
should not spend time debugging them, running them, or testing
them. These exercises are designed to have you think about what you're
doing without using the computer. You should feel free to use the
compiler to assist with syntactic errors, however, if you think this
will be useful.
You should type solutions to these problems using emacs (or some
editor on your own machine) and submit the solution using the submit
program:
submit100e link solution.cc README
(you may need to use ~ola/bin/submit100e if your path doesn't
have my bin in it).
Be sure to include your name, the time you spent, and a list
of collaborators in the README
file, and the solutions in the file solution.cc.
In all these problems assume that types Node
and TNode exist as shown below.
struct Node
{
string info;
Node * next;
Node(const string & s, Node * follow = 0) // constructor
{
info = s;
next = follow;
}
};
template
struct TNode
{
Kind info;
TNode * next;
TNode(const Kind & k, TNode * follow = 0) // constructor
{
info = k;
next = follow;
}
};
Problem 1: Counting
Complete the function TotalChars whose header is given below.
TotalChars returns the total number of occurrences
of the character ch in
all the strings in its parameter list.
You should use the string member function length() to find the
number of characters in a string and s[k]
for the value of the k-th character (indexing starts at 0).
You should write this function both recursively and iteratively
(non-recursively).
int TotalChars(Node * list, char ch)
// postcondition: returns # of occurrences of ch in all nodes of list
Problem 2: Replicate
Write the function
Replicate whose header is given below.
Replicate
adds new nodes to list so that nodes are replicated the number
of times specified by parameter count. For example, if
list is represented by
("apple","cat","xray")
Then the call Replicate(list,3)
should change list as shown below.
("apple","apple","apple","cat","cat","cat","xray","xray","xray")
Note that list is not passed by reference.
void Replicate(Node * list,int count)
// precondition: list = a1, a2, ... an
// 1 < count
// postcondition: list = a1, a1, ... a1, ... an, an, ... an
// where each element appears count times
Problem 3: Reverse
Complete the function Reverse whose header is given below.
Reverse reverses the nodes of its parameter
list. You should do this by manipulating pointers, not by
swapping info fields. In writing Reverse you should maintain as
an invariant the picture shown below. This invariant
would be initialized by the statement: rev = NULL, where
rev is a local variable, since
initially no nodes have been reversed and all nodes need to be reversed.
void Reverse(Node * & list)
//precondition: list is represented by a1, a2, a3, ..., an
//postcondition: list is represented by an, ..., a3, a2, a1
Here's the invariant. The picture should be "true" each time the loop
test is evaluated.
Problem 4: Remove
Write a function Remove that removes all nodes containing
a specified item from a templated list. Assume that lists do
not have header
nodes. The call Remove(slist,"big") should remove all nodes
containing the string "big" from a list whose first node is
pointed to by slist defined as
TNode * slist;
The call Remove(ilist,33) should remove all nodes containing 33
from a list whose first nodes is pointed to by ilist defined as
TNode * ilist;
Write Remove recursively.
template
void Remove(TNode * & list,const Kind & deadValue)
// postcondition: all nodes containing deadValue have been removed
// from list
Problem 5: Split++
Write a function ListSplit that
will split a circular
list containing an even number of nodes, say 2k,
into two circular lists each of which contains k nodes.
The function should
have three parameters and should work so that the function call
ListSplit(list,sub1,sub2);
will create new lists pointed to by parameters sub1, and sub2 from the
list initially referenced by parameter list. After ListSplit
has executed, the first parameter should be 0/NULL, i.e., new nodes are
not
created, but are redistributed evenly between the second and third
parameters. It doesn't matter how you divide the nodes between the two
lists.
The prototype for the function is:
template <class Kind>
void ListSplit(TNode<Kind> * & list,
TNode<Kind> * & first, TNode<Kind> * & second);
(you should write a postcondition for the function)