views:

99

answers:

3

Judging from the title, I kinda did my program in a fairly complicated way. BUT! I might as well ask anyway xD

This is a simple program I did in response to question 3-3 of Accelerated C++, which is an awesome book in my opinion.

I created a vector:

vector<string> countEm;

That accepts all valid strings. Therefore, I have a vector that contains elements of strings.

Next, I created a function

int toLowerWords( vector<string> &vec )
{
    for( int loop = 0; loop < vec.size(); loop++ )
        transform( vec[loop].begin(), vec[loop].end(),
            vec[loop].begin(), ::tolower );

that splits the input into all lowercase characters for easier counting. So far, so good.

I created a third and final function to actually count the words, and that's where I'm stuck.

int counter( vector<string> &vec )
{

for( int loop = 0; loop < vec.size(); loop++ )
    for( int secLoop = 0; secLoop < vec[loop].size(); secLoop++ )
    {
        if( vec[loop][secLoop] == ' ' )

That just looks ridiculous. Using a two-dimensional array to call on the characters of the vector until I find a space. Ridiculous. I don't believe that this is an elegant or even viable solution. If it was a viable solution, I would then backtrack from the space and copy all characters I've found in a separate vector and count those.

My question then is. How can I dissect a vector of strings into separate words so that I can actually count them? I thought about using strchr, but it didn't give me any epiphanies.


Solution via Neil:

stringstream ss( input );
while( ss >> buffer )
    countEm.push_back( buffer );

From that I could easily count the (recurring) words.

Then I did a solution via Wilhelm that I will post once I re-write it since I accidentally deleted that solution! Stupid of me, but I will post that once I have it written again ^^

I want to thank all of you for your input! The solutions have worked and I became a little better programmer. If I could vote up your stuff, then I would :P Once I can, I will! And thanks again!

+2  A: 

If the words are always space separated, the easiest way to split them is to use a stringstream:

string words = ....   // populat
istringstream is( words );

string word;
while( is >> word ) {
   cout << "word is " << word << endl;
}

You'd want to write a function to do this, of course, and apply it to your strings. Or it may be better not to store the strings at allm but to split into words on initial input.

anon
Hey! I haven't ever used istringstream, so I don't really know what kind of magic you're working here, but I'll let you know if I can solve the problem with this solution ^^ So thanks for that! As with above, I will tick positive once I have the permission for it.
SoulBeaver
+2  A: 

You can use std::istringstream to extract the words one by one and count them. But this solution consumes O(n) in space complexity.

string text("So many words!");
size_t count =  0;
for( size_t pos(text.find_first_not_of(" \t\n"));
    pos != string::npos;
    pos = text.find_first_not_of(" \t\n", text.find_first_of(" \t\n", ++pos)) )
    ++count;

Perhaps not as short as Neil's solution, but takes no space and extra-allocation other than what's already used.

wilhelmtell
Thanks for the reply ^^ I can't vote yet so I'll respond to your reply. I haven't heard some of the syntax you're using, so I'm researching it a little, and I'll let you know how I fare with it, but thanks for the helper !
SoulBeaver
Apart from a semantic error I had (`text::npos` instead of `string::npos`, which I just corrected) there's nothing special about the syntax. Maybe the indentation got you confused... It's a simple `for` loop, really.
wilhelmtell
... and a logic error. ew, i should really test my code before i post it. :s
wilhelmtell
It's okay, I figured out the problems when it was my turn to write it. Your solution was still valid, so cheers and thanks! I will post it in an edit so other people can see once I re-write it. Thanks!
SoulBeaver
+1  A: 

Use a tokenizer such as the one listed here in section 7.3 to split the strings in your vector into single words (or rewrite it so that it just returns the number of tokens) and loop over your vector to count the total number of tokens you encounter.

jilles de wit
Hey Jiles! I've started reading on that and I've thought of using a tokenizer, but I found strchr before I could look up strtok and it's safer equivalent. I'll let you, too, know if I can answer it with this solution, since I want to use them all as a possible answer so I can be as versatile as possible later on ^^
SoulBeaver