Code:
/**********************************************************
* Created by Bryan Stern on 2/23/07.
*********************************************************/
#include <cstring>
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
/**********************************************************
* Utility Methods Useful to both Classes
*********************************************************/
/*
* Precondition:
* Postcondition:
* "0-based" Alphabet such that A = 0, B = 1, etc...
*/
int getCharAlphPos(char x){
return (int)x - 65;
}
/*
* Precondition:
* Postcondition:
* "0-based" Alphabet such that A = 0, B = 1, etc...
*/
char getAlphPosChar(int x){
return (char)(x + 65);
}
/**********************************************************
* Node Class and Methods
*********************************************************/
class Node {
public:
Node();
Node(char letter, bool wordend);
char getChar();
bool contains(char x);
Node getDaughterNode(char x);
bool addNode(Node x);
void increaseWPCount();
void increasePCount();
int getWordCount();
int getPrefixCount();
int daughterNodeCount();
private:
int capacity;
char value;
bool end;
Node *nodes;
int wordCount;
int prefixCount;
int daughterCount;
};
/*
* Precondition:
* Postcondition:
*/
Node::Node(){
wordCount = 0;
prefixCount = 0;
daughterCount = 0;
const int capacity = 26;
nodes = new Node[capacity];
}
/*
* Precondition:
* Postcondition:
*/
Node::Node(char letter, bool wordend): value(letter){
wordCount = 0;
prefixCount = 1;
daughterCount = 0;
const int capacity = 26;
nodes = new Node[capacity];
if (wordend){
wordCount++;
}
}
/*
* Precondition:
* Postcondition:
*/
char Node::getChar() {
return value;
}
/*
* Precondition: x must be an uppercase letter
* Postcondition:
*/
bool Node::contains(char x) {
if (nodes[getCharAlphPos(x)].getChar() == x){
return true;
}
return false;
}
/*
* Precondition: x must be an uppercase letter
* Postcondition:
*/
Node Node::getDaughterNode(char x){
return nodes[getCharAlphPos(x)];
}
/*
* Precondition: x must have been initiated with a char value
* Postcondition: word count is increased
*/
bool Node::addNode(Node x){
char xchar = x.getChar();
//If already a daughternode
if (contains(x.getChar())){
getDaughterNode(xchar).increaseWPCount();
} else {
daughterCount++;
}
return true;
}
/*
* Precondition: none
* Postcondition: prefixCount = prefixCount + 1, wordCount = wordCount + 1
*/
void Node::increaseWPCount(){
wordCount++;
prefixCount++;
}
/*
* Precondition: none
* Postcondition: prefixCount = prefixCount + 1
*/
void Node::increasePCount(){
prefixCount++;
}
int Node::getWordCount(){
return wordCount;
}
int Node::getPrefixCount(){
return prefixCount;
}
int Node::daughterNodeCount(){
return daughterCount;
}
/**********************************************************
* Tree Class and Methods
*********************************************************/
class Tree {
public:
Tree();
bool add(string word);
int find(string word);
int prefixCount(string prefix);
void printPrefix(string prefix);
private:
Node root;
void insertLetters(Node parent, string word);
int findWord(Node parent, string word, int pos);
int prefixCountHelper(Node parent, string word, int pos);
void printPrefixHelperP1(Node parent, string prefix, int pos);
void printPrefixHelperP2(Node parent, string prefix);
};
/*
* Precondition:
* Postcondition:
*/
Tree::Tree(){}
//If word empty or null, return false
/*
* Precondition:
* Postcondition:
*/
bool Tree::add(string word){
if (/*word == NULL ||*/ word.empty())
return false;
insertLetters(root, word);
return true;
}
/*
* Precondition:
* Postcondition:
*/
void Tree::insertLetters(Node parent, string word){
if (!word.empty()){ // base case
if (parent.contains(word.at(0))){
Node temp = parent.getDaughterNode(word.at(0));
if (word.size() == 1){ //Is the end of a word, mark that
temp.increaseWPCount();
//By not calling insert from here, acts almost as a second base case
} else { //Not the end of a word, so the letter is a prefix
temp.increasePCount();
//Reformatting array
word = word.substr(1, word.length() - 1);
insertLetters(temp, word);
}
} else { //Create node and add it
if(word.size() == 1){
parent.addNode(Node(word.at(0), true));
} else {
parent.addNode(Node(word.at(0), false));
}
Node temp = parent.getDaughterNode(word.at(0));
//Reformatting array
word = word.substr(1, word.length() - 1);
insertLetters(temp, word);
}
}
}
//if word null or emptry, return -1
/*
* Precondition:
* Postcondition:
*/
int Tree::find(string word){
if (word.empty()/* || word == NULL*/)
return -1;
return findWord(root, word, 0);
}
/*
* Precondition:
* Postcondition:
*/
int Tree::findWord(Node parent, string word, int pos){
if (!parent.contains(word.at(pos))){ //if parent node does not have any daughters with this char
return 0;
} else {
Node daughter = parent.getDaughterNode(word.at(pos));
if (word.length() == ((unsigned)pos + 1)) //if at the end of the word return the last nodes word count
return daughter.getWordCount();
return findWord(daughter, word, pos++); //otherwise continue recursing through tree
}
}
/*
* Precondition:
* Postcondition:
*/
int Tree::prefixCount(string prefix){
if (prefix.empty()/* || prefix == NULL*/)
return -1;
return prefixCountHelper(root, prefix, 0);
}
/*
* Precondition:
* Postcondition:
*/
int Tree::prefixCountHelper(Node parent, string prefix, int pos){
if (!parent.contains(prefix.at(pos)))
return 0;
Node daughter = parent.getDaughterNode(prefix.at(pos));
if ((prefix.length() - 1) == (unsigned)pos)
return daughter.getPrefixCount();
return prefixCountHelper(daughter, prefix, pos++);
}
/*
* Precondition:
* Postcondition:
*/
void Tree::printPrefix(string prefix){
if (prefix.empty()/* || prefix == NULL*/)
return;
printPrefixHelperP1(root, prefix, 0);
}
/*
* Precondition:
* Postcondition:
*/
void Tree::printPrefixHelperP1(Node parent, string prefix, int pos){
if(parent.contains(prefix.at(pos))){
if (((unsigned)pos + 1) == prefix.length()){ //Have reached the last letter of the prefix
printPrefixHelperP2(parent, prefix);
} else { //Otherwise keep moving
printPrefixHelperP1(parent, prefix, pos++);
}
}
}
/*
* Precondition:
* Postcondition:
*/
void Tree::printPrefixHelperP2(Node parent, string prefix){
prefix = prefix + parent.getChar();
for (int i = 0; i < parent.getWordCount(); i++){
cout << prefix << endl;
}
for (int i = 0; i < 26; i++){
printPrefixHelperP2(parent.getDaughterNode(getAlphPosChar(i)), prefix);
}
}
/**********************************************************
* CharTree Driver
*********************************************************/
/*
* Precondition:
* Postcondition:
*/
int main(int argc, char * argv[]){
if (argc != 2){
cerr << "Usage: chartree filename.txt" << endl;
return 0;
} else {
//Read file into tree
ifstream inFile;
string temp;
Tree cTree;// = new Tree();
inFile.open(argv[1]);
if(!inFile) {
cout << "Unable to open file" << endl;
return 0;
}
while (inFile >> temp){
cTree.add(temp);
}
inFile.close();
cout << "File successfully loaded..." << endl;
//Finally running the pig
while (true){
int selection = 0;
while(selection == 0){
cout << "Select an operation to perform on the Word Tree" << endl;
cout << "1. Insert new word\n2. Search for word\n3. Number of words starting with...\n4. Words starting with...\n5. Quit" << endl;
cin >> selection;
}
if (selection == 1){
//Inserting a Word into the Tree
cout << "Enter the word you wish to insert. Must be all uppercase letters" << endl;
string temp;
cin >> temp;
if(cTree.add(temp))
cout << "Word added successfullly" << endl;
else
cout << "Error while addign word" << endl;
} else if (selection == 2){
//Searching for a word into the tree
cout << "What word do you wish to search for?" << endl;
string temp;
cin >> temp;
int numFound = cTree.find(temp);
if (numFound == 0)
cout << temp << " was not present in tree, check spelling" << endl;
else
cout << temp << " was found " << numFound << " time(s)" << endl;
} else if (selection == 3){
//Finding number of words with prefix...
cout << "Enter a prefix to find the number of words using it" << endl;
string prefix;
cin >> prefix;
cout << cTree.prefixCount(prefix) << " word(s) start with " << prefix << endl;
} else if (selection == 4){
//Pring all words with prefix...
cout << "Enter a prefix to see all words using it" << endl;
string prefix;
cin >> prefix;
cTree.printPrefix(prefix);
} else if (selection == 5){
//Quit
break;
}
}
return 0;
}
}
I'm pulling my hair out trying to get this fucker to run.
Bookmarks