-
Notifications
You must be signed in to change notification settings - Fork 0
/
Dictionary.cpp
170 lines (147 loc) · 4.75 KB
/
Dictionary.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#include "Dictionary.h"
Dictionary::Node::Node() {
isWord = false;
for (int i = 0; i < NUM_CHARS; i++) {
next[i] = nullptr;
}
}
Dictionary::Dictionary() {
root = new Node;
numWords = 0;
}
Dictionary::~Dictionary() {
}
Dictionary::Dictionary(string filename) {
root = new Node;
numWords = 0;
LoadDictionaryFile(filename);
}
void Dictionary::LoadDictionaryFile(string filename) {
string word;
ifstream infile;
infile.open(filename);
if (!infile.is_open()) {
cout << "Could not open file" << endl;
return;
}
while (!infile.eof()) {
//add all words from file into dictionary
infile >> word;
AddWord(word);
}
infile.close();
}
void Dictionary::AddWord(string word) {
Node *currNode = root;
//search through each character
for (int i = 0; i < word.size(); i++) {
int charIndex = int(word[i]) - int('a'); //the index for the char in the string word
if (currNode->next[charIndex] == nullptr) {
//set branch of character to new Node
Node *newNode = new Node; //make new path
currNode->next[charIndex] = newNode;
}
currNode = currNode->next[int(charIndex)];
}
currNode->isWord = true; //end of word is reached so this is now valid word
numWords++;
}
bool Dictionary::IsWord(string word) {
Node *currNode = root;
//search through each character
for (int i = 0; i < word.size(); i++) {
int charIndex = int(word[i]) - int('a'); //the index for the char in the string word
if (charIndex < 0 || charIndex > 25) { //make sure that the character is valid
throw (DictionaryError("Invalid character"));
}
if (currNode->next[charIndex] == nullptr) { //return false if path does not exist
return false;
}
currNode = currNode->next[int(charIndex)];
}
if (currNode->isWord == true) {
return true; //return true if valid word
}
return false; //return false if invalid word
}
bool Dictionary::IsPrefix(string word) {
Node *currNode = root;
//search through each character
for (int i = 0; i < word.size(); i++) {
int charIndex = int(word[i]) - int('a'); //the index for the char in the string word
if (charIndex < 0 || charIndex > 25) { //make sure that the character is valid
throw (DictionaryError("Invalid character"));
}
if (currNode->next[charIndex] == nullptr) {
return false;
}
currNode = currNode->next[int(charIndex)];
}
return true; //return true if valid prefix
}
int Dictionary::WordCount() {
return numWords;
}
void Dictionary::MakeEmpty() {
destroyHelper(root);
root = new Node;
numWords = 0;
}
void Dictionary::destroyHelper(Dictionary::Node *thisTree) {
if (thisTree == nullptr) { //base case
return;
}
for (int i = 0; i < NUM_CHARS; i++) { //traverse tree
destroyHelper(thisTree->next[i]);
}
delete thisTree; //delete nodes
}
Dictionary &Dictionary::operator=(const Dictionary &otherDict) {
this->MakeEmpty(); //make empty clears a tree and resets root
numWords = otherDict.numWords;
for (int i = 0; i < NUM_CHARS; i++) { //traverse for root since one already exists
copyHelper(root->next[i], otherDict.root->next[i]);
}
return *this;
}
void Dictionary::copyHelper(Dictionary::Node *&thisTree, Dictionary::Node *&otherTree) {
if (otherTree == nullptr) { //base case
thisTree = nullptr;
return;
}
thisTree = new Node; //add data to new nodes
thisTree->isWord = otherTree->isWord;
for (int i = 0; i < NUM_CHARS; i++) { //traverse all nodes
copyHelper(thisTree->next[i], otherTree->next[i]);
}
}
void Dictionary::SaveDictionaryFile(string filename) {
ofstream outfile;
outfile.open(filename);
//throw error message if file could not open
if (!outfile.is_open()) {
string msg = filename;
msg = msg + " failed to open";
throw (DictionaryError(msg));
}
//write the words to file if open
SaveDictionaryHelper(root, "", outfile);
outfile.close();
}
void Dictionary::SaveDictionaryHelper(Dictionary::Node *curr, string currPrefix, ofstream &outFile) {
if (curr == nullptr) { //base case
return;
}
if (curr->isWord) {
outFile << currPrefix << endl; //write data
}
for (int i = 0; i < NUM_CHARS; i++) {
//call for every element of array and update prefix with the current character
SaveDictionaryHelper(curr->next[i], currPrefix + (char) (i + (int) 'a'), outFile);
}
}
Dictionary::Dictionary(const Dictionary &otherDict) {
root = new Node;
numWords = 0;
*this = otherDict;
}