#include "grid.h"
//constructing a Grid Grid<int> matrix(3, 4); matrix[0][0] = 75; ....or
//constructing a Grid
Grid<int> matrix = {
{75, 61, 83, 71},
{94, 89, 98, 100},
{63, 54, 51, 49},
};
Pictorially, the matrix looks like:
row/col 0 1 2 3 0 75 61 83 71 1 94 89 98 100 2 63 54 51 49
| Member function name | Description |
|---|---|
Grid<type> name(r, c);
or Grid<type> name; |
create grid with given number of rows/columns; empty 0x0 grid if omitted. |
g[r][c] or g.get(r, c)
|
returns value at given row/col. |
g.fill(value)
|
set every cell to store the given value. |
g.inBounds(r, c)
|
returns true if given position is in the grid. |
g.numCols() or g.width()
|
returns number of columns. |
g.numRows() or g.height()
|
returns number of rows. |
g.resize(nRows, nCols)
|
resizes grid to new size, discarding old contents. |
g[r][c] = value or g.set(r, c, value)
|
stores value at given row/col. |
g.toString()
|
returns a string representation of the grid such as "{{1, 3}, {-8, 2}, {-3, -4}, {4, 7}}". |
cout << g
|
prints, e.g., "{{1, 3}, {-8, 2}, {-3, -4}, {4, 7}}". |
for (int r = 0; i < grid.numRows(); r++) {
for (int c = 0; c < grid.numCols(); c++) {
//do something with grid[r][c]
}
for (int value : grid) {
//do something with value (don't have access to row/col number)
}
for (int c = 0; c < grid.numCols(); c++) {
for (int r = 0; i < grid.numRows(); r++) {
//do something with grid[r][c]
}
Which one is best?
int computeSum(Grid<int> g) { ...}int computeSum(Grid<int> &g) { ...}int computeSum(const Grid<int> g) { ...}int computeSum(const Grid<int> &g) { ...} : BestWhich one is best?
int invert(Grid<double> g) { ...} : will not workint invert(Grid<double> &g) { ...} : Bestint invert(const Grid<double> g) { ...} : will not workint invert(const Grid<double> &g) { ...} : will not workExercise: Write a function knightCanMove that accepts a grid
and two row/column pairs (r1, c1), (r2, c2)
as parameters, and returns true if there is a knight at chess
board square (r1, c1) that can legally move to empty square (r2, c2).
knightCanMove(board, 1, 2, 2, 4) returns true.
bool knightCanMove(Grid<string> const &board, int r1, int c1, int r2, int c2)
{
if (!board.inBounds(r1, c1) || !board.inBounds(r2, c2)) {
return false;
}
if (board[r1][c1] != "knight" || board[r2][c2] != "") {
return false;
}
int dr = abs(r1 - r2);
int dc = abs(c1 - c2);
if (!((dr == 1 && dc == 2) || (dr == 2 && dc == 1))) {
return false;
}
return true;
}
Another solution:
bool knightCanMove(Grid& board, int r1, int c1, int r2, int c2) { int dr = abs(r1 - r2), dc = abs(c1 - c2); return board.inBounds(r1, c1) && board.inBounds(r2, c2) && board[r1][c1] == "knight" && board[r2][c2] == "" && ((dr == 1 && dc == 2) || (dr == 2 && dc == 1)); }
addFive() method that adds 5 to each
element of the grid: in the first version, the input grid itself is modified;
in the second version, a new output grid is returned as a return value.
#includeAn istringstream lets you "tokenize" a string.
istringstream input("abc def 123 456");
string first, last, phone;
int age;
input >> first >> last; //first = "abc", last = "def", removes whitespace
input >> phone; //phone = "123"
input >> age; //age = 123
Another example: read all tokens from a string
istringstream input2("abc def 123 456 hello world");
string word;
while (input2 >> word) {
cout << word << endl; //abc\ndef\n123\n456\n...
}
String streams are similar to I/O streams. e.g., cin>>word behaves similarly to input2>>word. The difference is that in the first case the input is read from the console (e.g., keyboard); in the second case the input is read from a string (stringstream).
An ostringstream lets you write output into a string buffer. Use the str member function to extract the string that was built.
int age = 42, iq = 95; ostringstream output; output << "abc's age is " << age << endl; output << " and his IQ is " << iq << "!" << endl; string result = output.str(); //this construct allowed us to convert integers and newline characters into strings. result = "abc's age is 42\nand his IQ is 95!\n"
getline function (notice small l) for getting a line of input from the console input stream.
cout << "What is your name? "; string name; getline(cin, name); //breaks on newline characters cout << "Hi " << name << endl;
But, do not mix >> and getline on the same input stream! Not recommended and will give unexpected results.
cout << "How old are you? "; int age; cin >> age; //user input: 17\n cout << "And what's your name? "; string name; getline(cin, name); //user input: abc\n cout << "Wow, " << name << " is " << age << "!" << endl;Output of the above program:
How old are you: 17 And what's your name: abc Wow, is 17!Notice that the
name was not read correctly because of mixing of >> and getline on the same input stream.
Advice for this course: always use Stanford getXxx methods to read from cin.
Exercise: write a function string_stats that prints statistics about the data in a string (passed an argument).
string s = "Hello I am really enjoying COL100.\nWhat a wonderful course this is.\nI am glad that I chose IIT Delhi\n\nI am sure this will help me in future\n"; string_stats(s);For this string, the function should print the following output:
Line 1: 34 chars, 6 words Line 2: 32 chars, 5 words Line 3: 32 chars, 8 words Line 4: 0 chars, 0 words Line 5: 37 chars, 9 words longest = 37 chars, average = 27.0 chars
Solution
/* Prints length/count statistics about data in the given file. */
void inputStats2(string filename) {
ifstream input;
input.open(filename);
int lineCount = 0, longest = 0, totalChars = 0;
string line;
while (getline(input, line)) {
lineCount++;
totalChars += line.length();
if (longest < line.length()) {
longest = line.length();
}
int wordCount = countWords(line); // on next slide
cout << "Line " << lineCount << ": " << line.length()
<< " chars, " << wordCount << "words" << endl;
}
double average = (double) totalChars / lineCount;
cout << longest = " << longest
<< ", average = " << average << endl;
}
And here is the definition of countWords:
/* Returns the number of words in the given string. */
int countWords(string line) {
istringstream words(line);
int wordCount = 0;
string word;
while (words >> word) {
wordCount++;
}
return wordCount;
}