forked from aaronbloomfield/pdr
-
Notifications
You must be signed in to change notification settings - Fork 228
/
getWordInGrid.cpp
188 lines (170 loc) · 6.52 KB
/
getWordInGrid.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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
/** This file defines and demonstrates two necessary components for
* the hash table lab for CS 2150. The first is the use of the
* getWordInGrid() function, which is used for retrieving a word in a
* grid of letters in one of the cardinal 8 directions (north,
* south-east, etc). The second is the use of file streams to read in
* input from a file, specifically one formatted as per the lab 6
* guidelines.
*
* Written by Aaron Bloomfield, 2009
*/
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
// We create a 2-D array of some big size, and assume that the grid
// read in will be less than this size (a valid assumption for lab 6)
#define MAXROWS 500
#define MAXCOLS 500
char grid[MAXROWS][MAXCOLS];
// Forward declarations
bool readInGrid(string filename, int& rows, int& cols);
string getWordInGrid(int startRow, int startCol, int dir, int len,
int numRows, int numCols);
/** The main() function shows how to call both the readInGrid()
* function as well as the getWordInGrid() function.
*/
int main() {
// to hold the number of rows and cols in the input file
int rows, cols;
// attempt to read in the file
bool result = readInGrid("5x8.grid.txt", rows, cols);
// if there is an error, report it
if (!result) {
cout << "Error reading in file!" << endl;
return 1;
}
// Get a word (of length 10), starting at position (2,2) in the
// array, in each of the 8 directions
cout << endl;
for (int i = 0; i < 8; i++) {
cout << i << ": " << getWordInGrid(2, 2, i, 10, rows, cols) << endl;
}
return 0;
}
/** This function will read in a grid file, as per the format in the
* CS 2150 lab 6 document, into a global grid[][] array. It uses C++
* file streams, and thus requires the the <fstream> #include header.
*
* @return true or false, depending on whether the file was
* successfully opened.
* @param filename The file name to read in -- it's assumed to be in
* the file format described in the lab document.
* @param rows The number of rows as specified in the input file;
* as this is a reference, it is set by the function.
* @param cols The number of columns as specified in the input file;
* as this is a reference, it is set by the function.
*/
bool readInGrid(string filename, int& rows, int& cols) {
// try to open the file
ifstream file(filename);
// upon an error, return false
if (!file.is_open()) {
return false;
}
// first comes the number of rows
file >> rows;
cout << "There are " << rows << " rows." << endl;
// then the columns
file >> cols;
cout << "There are " << cols << " cols." << endl;
// and finally the grid itself
string data;
file >> data;
// close the file
file.close();
// convert the string read in to the 2-D grid format into the
// grid[][] array.
// In the process, we'll print the grid to the screen as well.
int pos = 0; // the current position in the input data
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
grid[r][c] = data[pos++];
cout << grid[r][c];
}
cout << endl;
}
return true;
}
/** This function will retrieve a word in a grid of letters in a given
* direction. If the end of the grid is encountered before the length
* of the desired string is reached, then a shorter string will be
* returned. The data is retrieved from a global char grid[][]
* array, which is assumed to be defined (and in scope). NOTE: The
* return value is a static string variable (for efficiency
* reasons), so a successive return value will overwrite a previous
* return value.
*
* @return A STATIC string containing the letters in the provided direction.
* @param startRow The starting (row,col) position to find the word.
* @param startCol The starting (row,col) position to find the word.
* @param dir The direction to move: 0 is north (upwards), 1 is
* northeast, and it rotates around clockwise until it
* reaches 7 for northwest.
* @param len The desired length of the string to return (assuming
* the edge of the grid is not reached--if the edge of the
* grid is reached, it will return as many characters as
* possible up to the edge of the grid, so the returned
* string may not have the same length as this parameter
* indicates).
* @param numRows The number of rows in the global char grid[][]
* array.
* @param numCols The number of columns in the global char grid[][]
* array.
*/
string getWordInGrid (int startRow, int startCol, int dir, int len,
int numRows, int numCols) {
// the static-ness of this variable prevents it from being
// re-declared upon each function invocation. It also prevents it
// from being deallocated between invocations. It's probably not
// good programming practice, but it's an efficient means to return
// a value.
static string output;
output.clear(); // Since it's static we need to clear it
output.reserve(256); // Can't set capacity in the constructor so do it the first time here
// the position in the output array, the current row, and the
// current column
int r = startRow, c = startCol;
// iterate once for each character in the output
for (int i = 0; i < len; i++) {
// if the current row or column is out of bounds, then break
if (c >= numCols || r >= numRows || r < 0 || c < 0) {
break;
}
// set the next character in the output array to the next letter
// in the grid
output += grid[r][c];
// move in the direction specified by the parameter
switch (dir) { // assumes grid[0][0] is in the upper-left
case 0:
r--;
break; // north
case 1:
r--;
c++;
break; // north-east
case 2:
c++;
break; // east
case 3:
r++;
c++;
break; // south-east
case 4:
r++;
break; // south
case 5:
r++;
c--;
break; // south-west
case 6:
c--;
break; // west
case 7:
r--;
c--;
break; // north-west
}
}
return output;
}