- Both Sections: Monday, December 10
- (Assignments submitted by Dec 7 will be graded for Dec 10)
Homework can submitted via email or printout by deadline.
Do not attempt to hypothesize on the cause of any "bugs" you find; just describe (in as much detail as possible) any problems your tests uncover.
Feel free to expand your test suite as necessary after December 5. The purpose of the delayed deployment is to encourage you to think about your testing strategy in the abstract first. Since black box testing is performed without consulting the implementation, not having it available right away should not be a problem.
class Compressor {
public:
static Compressor* MakeCompressor(bool removeWhitespace,
bool removeVowels,
const Dictionary* abbreviations);
virtual ~Compressor() { }
// Caller assumes ownership of output (for memory management)
virtual bool CompressMessage(const char* input, char*& output) = 0;
};
The Message Compressor takes a string as input and performs a series
of operations on it, with the intent of shortening its length without
rendering it illegible. The newer generation of mobile telephones
have the ability to display text messages, but the protocol requires
that these messages must be quite short (usually less than 160
characters). The Message Compressor could be used to shorten messages
(e.g. email) before they are forwarded to the phone.
Four compression strategies are available. One is always applied, the other three can applied optionally. They are:
Replace all newline characters with a single space. Replace all occurrences of consecutive whitespace (i.e., space, tab, newline) characters with a single space. This strategy is always applied.
When this compression strategy is applied, all whitespace between words is removed. To keep the word boundaries identifiable, the first letter of each word is capitalized.
When this compression strategy is applied, all vowels, except those appearing at the beginning of a word, are removed.
Given a list of phrases and abbreviations, convert any occurrences of the phrases in the message into their abbreviations. Do not remove any vowels from the abbreviations, even if the Vowel Removal option is selected. Phrases can be removed entirely by leaving the second field blank.
Here are some sample messages, compressed under four different configurations. The sample Abbreviation Dictionary used appears in the Appendix.
- "Mr. Watson. Come here. I need you."
- "Mr.Watson.ComeHere.INeedYou." [1+2]
- "Mr. Wtsn. Cm hr. I nd y." [1+3]
- "Mr.Wtsn.CmHr.INdY." [1+2+3]
- "MrWtsn.CmHr.INdU." [1+2+3+4*]
- "Four score and seven years ago"
- "FourScoreAndSevenYearsAgo" [1+2]
- "Fr Scr And Svn Yrs Ag" [1+3]
- "FrScrAndSvnYrsAg" [1+2+3]
- "4Scr&7YrsAg" [1+2+3+4*]
- See you monday at 4
- SeeYouMondayAt4 [1+2]
- S y mndy at 4 [1+3]
- SYMndyAt4 [1+2+3]
- CUMon@4 [1+2+3+4*]
To compress a message, call the method CompressMessage(). The method takes two arguments, both character pointers (C strings), but their are roles are drastically different. The first string must be the message to be compressed. The second is uninitialized at entry, but upon successful return (when the return value is true), will contain a string representing the compressed message. The caller assumes responsibility for that second string, and is expected to delete it.
class Dictionary {
public:
static Dictionary* MakeDictionary();
static Dictionary* MakeDictionary(const char* filename);
virtual ~Dictionary() { }
virtual bool AddToDictionary(const char* from, const char* to) = 0;
virtual bool RemoveFromDictionary(const char* from) = 0;
};
The Abbreviation Dictionary is a table mapping words and phrases (the
source) to other words or phrases (the
abbreviation). The dictionary can be constructed from within
a program (using the AddToDictionary() method) or it can be
built up out of a file, where each source/abbreviation pair on
its own line, with at least one tab character separating the source
phrase from the abbreviation. The abbreviation can be empty,
signifying that the source phrase should removed during compression.
RemoveFromDictionary() takes one string argument (the source) and returns a boolean, signifying whether the removal was successful. If the source provided does not appear in the dictionary, a false value is returned.
Dictionaries are constructed via the factory methods: MakeDictionary() and MakeDictionary(char *), the former returning an empty dictionary, and the latter returning a dictionary initialized with the entries found in the supplied file(name). The caller takes ownership of any dictionary objects constructed, and is expected to delete them when they are done with them.
#include <iostream.h>
#include "compress.h"
main() {
Compressor* comp =
Compressor::MakeCompressor(true, false, Dictionary::MakeDictionary());
char* out = 0;
char* in = "Four score and seven years ago";
bool b = comp->CompressMessage(in, out);
int lin = strlen(in);
cout << "IN:\t" << in << " (" << lin << ")" << endl;
if (b) {
int lout = strlen(out);
cout << "OUT:\t" << out << " (" << lout << ")" << endl;
cout << endl << "Compression rate: "
<< (100 * (lin - lout) / lin) << '%' << endl;
}
delete out;
delete comp;
}
one 1 two 2 three 3 four 4 five 5 six 6 seven 7 eight 8 nine 9 ten 10 eleven 11 twelve 12 and & at @ plus + see C you U for 4 the love Luv monday Mon tuesday Tue wednesday Wed thursday Thurs friday Fri saturday Sat sunday Sun towards to regarding Re as far as I know AFAIK in my humble opinion IMHO