Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion RandomWriter/RandomWriter.pro
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ win32 {
QMAKE_LFLAGS += -Wl,--stack,536870912
LIBS += -lDbghelp
LIBS += -lbfd
LIBS += -liberty
#LIBS += -liberty
LIBS += -limagehlp
}
macx {
Expand Down
84 changes: 83 additions & 1 deletion RandomWriter/src/RandomWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,91 @@
#include "random.h"
#include "strlib.h"
#include "vector.h"

#include "filelib.h"
#include "simpio.h"

using namespace std;

/* Function Prototypes */
string getSourceText();
Map<string,Vector<char>> analyzeText(string str, int k);
string findSeed(Map<string, Vector<char>> &map);
string generateText(Map< string,Vector<char>> &map, string str);

/* Constants */
const int NUMBER_OF_CHARACTERS = 2000;

int main() {
// TODO: fill in the code

string text = getSourceText(); // get the original text file into a string
cout << endl;
int k = getInteger("Choose order of analysis (1 to 10):"); // get the number of the order to build the model
Map<string,Vector<char>> map = analyzeText(text,k); // read a source text, build an order-k Markov model for it
string seed = findSeed(map); // get initial seed
string randomText = generateText(map, seed); // generating random text
cout << endl;
cout << randomText;

return 0;
}

/* This implementation prompts user for a filename and
* returns that file as a string.
*/
string getSourceText() {
cout << "Select one of the three source files: Hamlet.txt, Middlemarch.txt, and TomSawyer.txt." << endl;
ifstream stream;
cout << endl;
string filename = promptUserForFile(stream, "Please enter filename containing source text:");
string text = readEntireFile(filename);
return text;
}

/* This implementation takes in a string of text and an integer k. It returns
* a Map where each key is a k-character sequence found in the string.
* The associated value is a vector of all the characters that follow that
* seed in the string. This vector will likely contain multiple entries and
* duplicate values. These duplicates represent higher probability transitions
* from the Markov state.
*/
Map<string,Vector<char>> analyzeText(string text, int k) {
Map<string,Vector<char>> map;
for(int i = 0; i < text.length()-k; i++) {
map[text.substr(i,k)].add(text[i+k]);
}
return map;
}

/* Chooses the sequence that appears most frequently in the source.
* Sequences are stored in the map that is passed in. If there are
* several sequences tied for most frequent this implementation
* returns the last occurence of those sequences.
*/
string findSeed(Map<string, Vector<char>> &map) {
string seed;
int n = 0;
for(string seq : map) {
if(map.get(seq).size() > n) {
n = map.get(seq).size();
seed = seq;
}
}
return seed;
}

/* Implementation of generating random text.
*/
string generateText(Map<string, Vector<char>> &map, string str) {
cout << "Processing...";
cout << endl;
string seed = str;
string randomText = str;
for (int i = 0; i < NUMBER_OF_CHARACTERS; i++) {
int vectorLength = map[seed].size();
int indexDraw = randomInteger(0, vectorLength-1);
seed = seed.substr(1,seed.length()-1) + map[seed][indexDraw];
randomText += seed[seed.size()-1];
}
return randomText;
}
2 changes: 1 addition & 1 deletion WordLadder/WordLadder.pro
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ win32 {
QMAKE_LFLAGS += -Wl,--stack,536870912
LIBS += -lDbghelp
LIBS += -lbfd
LIBS += -liberty
#LIBS += -liberty
LIBS += -limagehlp
}
macx {
Expand Down
128 changes: 126 additions & 2 deletions WordLadder/src/WordLadder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,133 @@
#include "queue.h"
#include "simpio.h"
#include "vector.h"

using namespace std;

/* Function prototypes */
string getStartWord(Lexicon &dictionary);
string getDestinationWord(Lexicon &dictionary, int length);
Vector<string> findMetagrams(string word, Lexicon &dictionary);
Vector<string> findWordLadder(string startWord, string destinationWord, Lexicon &dictionary);
void printWordLadder(Vector<string> &ladder);

int main() {
// TODO: fill in the code
return 0;
/* Lexicon of English words. */
const string WORD_LIST = "EnglishWords.dat";
Lexicon dictionary(WORD_LIST);

Vector<string> wordLadder;

while(true){
/* Get the initial and final words */
string startWord = getStartWord(dictionary);
string destinationWord = getDestinationWord(dictionary, startWord.length());
/* Find and print word ladder */
wordLadder = findWordLadder(startWord, destinationWord, dictionary);
printWordLadder(wordLadder);
}
return 0;
}
/* Function prompts the user for the initial word, checks its presence in the dictionary.
* If the user enters a blank line terminates the program.
*/
string getStartWord(Lexicon &dictionary){
string startWord = "";
while (true) {
startWord = toLowerCase(getLine("Enter start word (RETURN to quit): "));
if (startWord == ""){
exit(0);
} else if (!dictionary.contains(startWord)){
cout << "Please enter a valid word!" << endl;
} else break;
}
return startWord;
}
/* The function prompts the user for the final word,
* check for it in the dictionary and matching the length of the first word.
*/
string getDestinationWord(Lexicon &dictionary, int length){
string destinationWord = "";
while (true) {
destinationWord = toLowerCase(getLine("Enter destination word: "));
if (dictionary.contains(destinationWord) && destinationWord.length() == length){
break;
} else if (!dictionary.contains(destinationWord) && !(destinationWord.length() == length)){
cout << "Please enter a valid word of " << length << " letters!" << endl;
} else if (!dictionary.contains(destinationWord)){
cout << "Please enter a valid word!" << endl;
} else if (!(destinationWord.length() == length)){
cout << "Destination word must be " << length << " letters!" << endl;
}
}
return destinationWord;
}
/* The function takes an original word and finds it Metagrams in the dictionary.
* Returns vector Metagrams.
*/
Vector<string> findMetagrams(string parentalWord, Lexicon &dictionary){
Vector<string> metagrams;
string tmp = "";

for (int i = 0; i < parentalWord.length(); i++){
for (char ch = 'a'; ch <= 'z'; ch++){
tmp = parentalWord;
tmp[i] = ch; // generation word
if (tmp != parentalWord && dictionary.contains(tmp)){ // check in dictionary and unique
metagrams.add(tmp); // add to vector
}
}
}
return metagrams;
}
/* Function finds the word ledder between two words
* using Breadth-first search algorithm.
*/
Vector<string> findWordLadder(string startWord, string destinationWord, Lexicon &dictionary){

Vector<string> wordLadder;
Vector<string> emptyWordLadder;
Lexicon usedWords;
Queue<Vector<string>> ladders;

wordLadder.add(startWord);
usedWords.add(startWord);
ladders.enqueue(wordLadder);

while (!ladders.isEmpty()){
wordLadder = ladders.dequeue(); // Removes and returns the first item in the queue.
// short ladder found if last element of word ladder == destination word
if (wordLadder[wordLadder.size() - 1] == destinationWord){
return wordLadder; //
}
// Looking Metagrams for the word standing at the end of the current ladder.
Vector<string> metagrams = findMetagrams(wordLadder[wordLadder.size() - 1], dictionary);
// Looking at Metagrams words have not been used before and are adding to the ladders
for(string word : metagrams){
if(!usedWords.contains(word)){
usedWords.add(word);
Vector<string> tmp = wordLadder;
tmp.add(word);
ladders.enqueue(tmp);
}
}
}
return emptyWordLadder;
}
/* The function displays the ladder of words or a message about her absence. */
void printWordLadder(Vector<string> &ladder){
if(ladder.size() > 0){
for (int i = 0; i < ladder.size(); i++){
if (i < ladder.size() - 1){
cout << ladder[i] << " -> ";
}
else {
cout << ladder[i] << endl;
}
}
}
else {
cout << "Word ladder not found." << endl;

}
}