Re: Accelerate C++ Exercise 4-5 Questions
bwaichu@yahoo.com wrote:
This time I decided to tackle the problem of reading input into a
vector, counting the number of words entered, and counting the
number of time each word was entered.
My code works, but I'm not sure about cin and the << operator
behavior. I enter a complete sentence followed by ^D (EOF) on BSD.
On windows, it's a little trickier to get the EOF with ^Z to
register. I need to enter it more than once for some reason. What
does the C++ specification say about cin behavior, or this behavior
undefined?
I haven't seen this behavior on Windows. You might have to press Enter
to have your input processed.
cin reads one word at a time, rather than the complete line. The
good news is that this makes it easier to split words, so I can
populate my vector. However, this becomes very inefficient in
terms of the number of calls I need to make. Is there a better C++
approach?
Are you in a hurry? :-)
It is always better to have the program work correctly, rather than
fast. If needed, you can look into the execution speed later, or buy a
bigger computer.
If you want to get one line at a time, there is a function for that -
getline.
Also, I'm iterating through all most the entire vector each time
before adding a new word. Does the STL provide a better way to look
up strings?
There is a better container for mappning a string to an int
(std::map), but you don't know about that until chapter 7.2. :-)
Are there string search functions within the STL such
as Boyer-Moore, or do I need to write my own implementation? I do
enjoy the operator overloading in C++.
There are string search functions, but perhaps not Boyer-Moore.
Anyway, please provide me some feedback.
Thanks,
Brian
Here's my code:
#include <iostream>
#include <vector>
using namespace std;
struct Words {
string word;
int count;
};
istream&
read(istream& in, Words& record, vector<Words>& wVec) {
I wouldn't use a parameter for the record, as it seems to used only
inside this function. You could have a local variable for that.
bool eflag = 0;
I have to look through the code to see what an eflag could be. Perhaps
you could use a more descriptive name?
Also, the bool values are true and false, not 0 and 1.
// add record
if (in >> record.word) {
if (wVec.size() == 0 ) {
record.count = 1;
wVec.push_back(record);
}
This special case is not really needed, as the for loop below will
terminate immediately on an empty vector - begin() equals end().
else {
// iterate through all the words all ready pushed into
the vector
for (vector<Words>::iterator i = wVec.begin();
i != wVec.end(); ++i) {
// test to see if the word has all ready been entered
if (i->word == record.word) {
i->count += 1;
eflag = 1;
break;
}
}
if (eflag == 0) {
record.count = 1;
wVec.push_back(record);
}
}
}
return in;
}
int
main() {
vector<Words> wVec;
Words record;
int wc = 0;
while (read(cin,record, wVec)) {
++wc;
}
It is not at all obvious that the while loop terminates when cin
reaches end-of-file (or some error?). Could you make this more
readable.
I also don't really like wc as a variable name. How do I know that it
is a word count, and not the number of wide characters or wind
changes?
cout << "number of words entered: " << wc << endl;
// iterate through the vector and display the word and its count
for (vector<Words>::iterator i = wVec.begin();
i != wVec.end(); ++i) {
cout << i->word << " " << i->count << endl;
}
return 0;
}
Bo Persson
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]