| Date Assigned: | Wed Feb-7 |
| Date Due: | Fri Feb-9 |
This is a very straightforward demonstration of vectors, matrices, and strings. Here, we will keep track of how many times a group of students visit various local hangouts (Starbucks, Bruegers, etc).
First, read in a bunch of student names until you read in the word done. Store these in a vector of strings where the first name read in is studentNames[0], the second is studentNames[1], and so on.
Second, read in a bunch of hangouts until you read in the word done. Store these in another vector of strings where the first hangout read in is hangoutNames[0], the second is hangoutNames[1], and so on. Be sure to share code so that you only have one function, say loadNames(), which you call twice -- once for studentNames and once for hangoutNames.
Third, read in entries of when students go to various hangouts. This will be entered as 2 digits: student number and hangout number. You should have a matrix which keeps a count of how many times each student visits each hangout. Keep doing this until you read in -1 for a student number, indicating that there are no more entries to read in. Hint: You will probably want an apmatrix<int> named something like visitCounts, where the rows correspond to each student and the columns correspond to each hangout, and the value in visitCounts[row][col] are a count of how many times the rowth student visited the colth hangout.
Fourth, you should print out your report. Print out the following
information:
1. For each student, their most popular hangout and least popular
hangouts
2. The overall most popular and least popular hangouts
Sample output:
Most popular hangouts by student:Be sure to share code where possible, particularly when reading in the two vectors of names, and also for the code that determines most popular and least popular hangouts by student.
Steve: Starbucks
Janet: Bruegers
Pierre: GiantEagleLeast popular hangouts by student:
Steve: Bruegers
Janet: GiantEagle
Pierre: StarbucksOverall most popular hangout: Bruegers
Overall least popular hangout: Giant Eagle
Good luck!
DK
Q: Do I have to read this whole email?
Yes.
Q: When is assignment 37 due?
Tomorrow, after 4th period rotation (so you can work on it during rotation if you like).
Q: Has the code in the examples below been compiled?
No. It might contain an error or two. If so, please let me know (thanks).
Q: How do I read a word into a string?
Here is the code to do it:
apstring word;
cin >> word;
Now, to print it out, just do:
cout << word;
Q: How to access each letter inside a string?
The following code prints out the word character-by-character (not necessary, as you can cout << word, but useful for demonstrational purposes):
for (int i=0; i<word.length(); i++)
cout << word[i];
So say you want to change the 2nd letter of word to 'x'. This is done as follows:
word[1] = 'x'; // note that word[1] is the 2nd letter
Q: How to read in a vector of apstrings?
Here we will call our vector "sentence" (since what is a collection of words?). The following code reads in 10 words into a sentence:
typedef apvector<apstring> apstringVector;
apstringVector sentence;
sentence.resize(10);
for (int i=0; i<10; i++)
cin >> sentence[i]; // sentence[i] is the
ith word in the sentence -- it is an apstring
Q: Yes, but how to read in a vector of apstrings when you don't know the length?
Well, that's the homework, so we'll change it slightly here to read in a vector of integers when you don't know the length. The following code reads in integers until it reads in a 0, though this code is not sufficiently efficient -- we'll fix that in the next answer:
typedef apvector<int> intVector;
intVector v;
while (true)
{
cin >> input;
if (input == 0)
break;
// input is non-0, so add it to the vector but first
make room for it
v.resize(v.length() + 1);
v[v.length()-1] = input;
}
This code works, but the problem is that it keeps resizing every time, which is bad because each resize copies the entire vector to that point. So loading 20 numbers actually results in 1+2+3+4+...+20 copies, which is 20(21)/2 = 210 copies. Which is wasteful.
Q: Yes, but... We want to do that efficiently, so how do we do that?
Here we minimize the amount of resizing we do by *doubling* the vector on each resize. Because of this, we cannot use the length of the vector in order to determine where the next input goes, so we need to use a variable which indicates how many elements are actually used in the vector v. Finally, once we have v loaded, we can resize it one time (which will, due to the silly implementation of apvector, copy all the elements) to the exact size needed so that code can then use v.length() to determine how many elements are actually stored in v.
typedef apvector<int> intVector;
intVector v;
int elementsInV = 0;
while (true)
{
cin >> input;
if (input == 0)
break;
// input is non-0, so add it to the vector but first
make room for it
if (v.length() >= elementsInV)
// no room for new element,
so we must resize v
// choose a size roughly
double, but add 10 so that initially
// we aren't constantly
resizing
v.resize(2*elementsInV +
10);
// Now there is room, so put the input into v
v[elementsInV] = input;
elementsInV++;
}
// Ok, so now v is loaded, but it's length is larger than necessary.
// So here we can resize it one time down to the exact size needed.
v.resize(elementsInV);
Q: I have a vector of apstrings and I want to access the 2nd letter in the 4th word. How?
Here is a less-efficient way to do this, but it's clear. First, get the 4th word, then get the 2nd letter:
apstringVector sentence;
apstring fourthWord;
char secondLetter;
fourthWord = sentence[3];
secondLetter = fourthWord[1];
First, we can do that without using fourthWord as follows:
apstringVector sentence;
char secondLetter;
secondLetter = sentence[3][1];
The reason this works is that sentence[3] *is* fourthWord, and you can right there on the spot access the 2nd letter in it. This is not only useful, it's actually required if you want to *modify* the 2nd letter. As the next question addresses.
Q: How do I set the 2nd letter of the 4th word in a vector of apstrings to 'D'?
Well, here is how you do *not* do it:
apstringVector sentence;
apstring fourthWord;
fourthWord = sentence[3];
fourthWord[1] = 'D';
The problem is that "fourthWord" is actually a *copy* of the string in sentence[3], so setting fourthWord[1] to 'D' only works in the copy. One way around this is to simply copy the modified word back into the sentence as such:
apstringVector sentence;
apstring fourthWord;
fourthWord = sentence[3];
fourthWord[1] = 'D';
sentence[3] = fourthWord;
A second, more efficient way around this is:
apstringVector sentence;
sentence[3][1] = 'D';
This works, but if it confuses you, you have a third option: you can create a method which takes the fourth word of the sentence as its argument, but it takes it *by reference*, so that it really changes that word, as such:
void setSecondLetter(apstring& word)
{
word[1] = 'D';
}
apstringVector sentence;
setSecondLetter(sentence[3]);
Q: What is the difference between single quote (') and. double quote (")?
A single quoted letter, as in 'a', is a *character*. A double-quoted word, as in "hello", is a *string*. A string is made up of individual characters. You access the individual characters of a string using the same notation for accessing elements in a vector. To wit:
apstring word;
char secondLetter;
word = "Hello";
secondLetter = word[1];
word[1] = 'Q'; // not set the second letter of word to the letter 'Q'
Note that you set word[1] to 'Q'. It would be illegal (and nonsensical) to set word[1] to "Q". Even though 'Q' and "Q" look very similar, they in fact are very different. 'Q' is a single character, and "Q" is a string. Now, word[1] is the second letter of word, so it is in fact a character not a string (words are, after all, composed of characters, right?). That's why we must set it to 'Q' and not "Q".
Q: What is the meaning of life?
41.999999999 (well, that's when it's computed on a Pentium)
Q: How do we set up our projects for apvector, apstring, and apmatrix?
Good question. For apstring, you should include both apstring.cpp and apstring.h in your project, then #include apstring.h in your main.cpp.
For apvector and apmatrix, however, you must not include their corresponding cpp file in your project! Otherwise, it will not compile. You should only include the .h files in your project, and then you also #include the same .h files in your main.cpp.
Q: How do I get more of these kinds of questions answered?
Easy: just ask. :-)
DK