The problems listed here are essentially the same as what appears as "Project 6.(A-D)" in the book. However, I've made some changes to the code that affect 6.A and 6.B. and so here is an updated version of the problems.
You'll need the code from class to do these and test them in the interpreter, but you need to submit only the function you write for each problem. Enter them into the automatic grading system as "6.A" etc. You may do these with a partner, in which case simply include both your names when you submit.
6.A
Finish the following function adjoinSet
,
which takes a tree and a list of trees and
places the tree in the right place in the list to maintain that
list as sorted by frequency (least frequent to most frequent as in class, not
as it is in the book).
fun adjoinSet(x, []) = [x] | adjoinSet(x, fst::rest) = if freq(x) < freq(fst) then ?? else ??
6.B
Finish the function successiveMerge
.
Assume the list it receives is sorted.
It should merge the first two items, put the newly merged item
into the right place in the list (hint: use adjoinSet
),
and keep merging.
fun successiveMerge([x]) = x | successiveMerge(x::y::rest) = ??;
6.C
Finish the function encodeSymbol
.
It uses the case and option ML language features described
in Section 2.5.
fun encodeSymbol(sym, tree) = let fun encodeSymbol1(sy, Leaf(st, f)) = if sy = st then SOME [] else NONE | encodeSymbol1(sy, Internal(left, right, st, f)) = case (encodeSymbol1(sy, left), encodeSymbol1(sy, right)) of (NONE, NONE) => ?? | (NONE, SOME bits) => ?? | (SOME bits, x) => ?? in valOf(encodeSymbol1(sym,tree)) end;
(This all assumes that every character in the message actually occurs
somewhere in the tree.
If not, encodeSymbol1
will return NONE
, and
the line valOf(encodeSymbol1(sym, tree))
will crash.
Furthermore, the pattern (SOME bits, x)
assumes
x
will always be NONE
.)
6.D
Finish the function decode
.
It makes use of a function called
implode
, which is a standard
ML function and does the opposite of what
explode
does: it turns a list of characters into
a string.
fun chooseBranch(Zero, Internal(left, right, s, f)) = left | chooseBranch(One, Internal(left, right, s, f)) = right; fun decode(bits, tree) = let fun decode1([], currentBranch) = [] | decode1(b::rest, currentBranch) = let val nextBranch = chooseBranch(b, currentBranch) in case nextBranch of Leaf(sym, w) => ?? | Internal(left, right, syms, w) => ?? end; in implode(decode1(bits, tree)) end;