-
Notifications
You must be signed in to change notification settings - Fork 0
/
wordladder.cpp
151 lines (119 loc) · 4.13 KB
/
wordladder.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
#include <iostream>
#include <fstream>
#include <string>
#include <stack>
#include <vector>
#include <queue>
#include <set>
using namespace std;
/* Constants */
const int ALPHA_LENGTH = 26;
/* Prototypes */
void getWords(string &word1, string &word2);
void printWordLadder(string word1, string word2);
/* Main function */
int main() {
string word1, word2;
getWords(word1, word2);
printWordLadder(word1, word2);
return 0;
}
/*
* Function: getWords
* Usage: getWords(word1, word2)
* -----------------------------
* This function takes two strings as parameter (passed by reference),
* prompts the user for her input and stores her answer in those two
* parameters.
*
* The user must enter strings of same length, otherwise the function
* keeps asking for new words.
*/
void getWords(string &word1, string &word2) {
while (true) {
cout << "Please enter a word: ";
cin>>word1;
cout << "Please enter another word of the same length: ";
cin>>word2;
if (word1.length() == word2.length()) {
break;
}
cout << "Please enter two words with the same length." << endl;
}
}
/* Function: printWordLadder
* Usage: printWordLadder(word1, word2)
* ------------------------------
* This function takes two strings as parameters and prints the
* minimal word ladder between two words.
*
* A word ladder is a connection from one word to another formed
* by changing one letter at a time with the constraint that at each
* step the sequence of letters still forms a valid word.
*/
void printWordLadder(string word1, string word2){
// creates an empty queue of stacks
queue<stack<string> > myQueue;
//Create a stack which will contain a final word ladder
stack<string> wordladder;
// creates and adds a stack containing word1 to the queue
stack<string> myStack;
myStack.push(word1);
myQueue.push(myStack);
// creates two sets: one for the dictionary and one for the tested words
string token;
ifstream dictionary("dictionary.txt");
set<string> myDictionary;
set<string> testedWords;
if(dictionary.is_open()) {
while (dictionary >> token) {
myDictionary.insert(token);
}
// while the queue is not empty:
while (!(myQueue.empty())) {
// dequeue the partial-ladder stack from the front of the queue.
stack<string> ladder = myQueue.front();
myQueue.pop();
string word = ladder.top();
// if the word on top of the stack is the destination word:
if (word == word2) {
// Yeey! output the elements of the stack as the solution.
cout << "The ladder from " << word1 << " to " << word2 << " is \n";
//Copy the ladder stack to worldladder to take it in the order.
while(!ladder.empty()){
wordladder.push(ladder.top());
ladder.pop();
}
while(!wordladder.empty()){
cout<<wordladder.top()<<" > ";
wordladder.pop();
}
}
else {
// for each valid English word that is a "neighbor" (differs by 1 letter) of the word on top of the stack:
string test;
for (int i = 0; i < word.size(); i++) {
for (char j = 'a'; j <= 'z'; j++) {
test = word.substr(0, i) + j + word.substr(i + 1);
// if that word is an english word
if (myDictionary.count(test)) {
// if that neighbor word has not already been used in a ladder before:
if (!testedWords.count(test)) {
// create a copy of the current ladder stack.
stack<string> copy = ladder;
// put the neighbor word on top of the copy stack.
copy.push(test);
// add the copy stack to the end of the queue.
myQueue.push(copy);
}
}
// Add test to tested words because it is already used.
testedWords.insert(test);
}
}
}
}
} else {
cerr << "Couldn't open the dictionary" << endl;
}
}