1
vector <string> oneWordPhrase;
vector <string> twoWordPhrase;
vector <string> threeWordPhrase;    

string str="hello my is bob oh hey jay oh";

vector<string>::iterator it1;
vector<string>::iterator it2;

I broke the sentence up in str into individual words and stored them into vectors called oneWordPhrase. So, the vector will have a size of 7

for(it1=oneWordPhrase.begin(); it1!=oneWordPhrase.end(); it1++)
{
    if(it1+1 == oneWordPhrase.end())
        break;  /* if we reach the last element of the vector
                     get out of loop because we reached the end */
    twoWordPhrase.push_back(*it1 + ' ' + *(it1+1));
}//gets each 2 consecutive words in the sentence

cout<<"two word---------------\n";
for(int i=0; i<twoWordPhrase.size(); i++)
    cout<<twoWordPhrase[i]<<endl;

This produces the correct output:

hello my

my is

is bob

bob oh

oh hey

hey jay

jay oh

for(int i=0; i<twoWordPhrase.size()-1; i++)
{   
    it1=twoWordPhrase.begin()+i;
    it2=oneWordPhrase.begin()+i+2;
    if(it1==twoWordPhrase.end()-1)
        break; //signal break but doesnt work
    threeWordPhrase.push_back(*it1 + ' ' + *it2);
}
cout<<"three words-----------\n";
for(int i=0; i<threeWordPhrase; i++)
    cout<<threeWordPhrase[i]<<endl;

This produces the correct output but there are two lines of white space at the end

hello my is

my is bob

is bob oh

bob oh hey

oh hey jay

//whitespace

//whitespace

I also tried to use the iterator in my for loop to signal the break but it didn't work. Why is it printing two extra lines of white space?

user3239138
  • 143
  • 4
  • 17

1 Answers1

1

To answer the original question, the code posted was correct. As JosephMansfield suspected, there was a mistake in the display code (not posted), as demonstrated here.

Following comments on style and best-practice, I think the following is more idiomatic C++:

#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <iterator>

using namespace std;
typedef vector<string> strings;

int main() {
    string s = "one two three four five";

    /* stringstream is a stream just like std::cout
       but reads/writes from/to a string
       instead of the standard input/output */
    stringstream ss(s);

    /* std::vector has a 2 argument constructor
       which fills the vector with all elements between two iterators
       istream_iterator iterates throuw the stream as if
       using operator>> so it reads word by word */
    strings words = 
        strings(istream_iterator<string>(ss), istream_iterator<string>());

    strings threeWords;
    for(size_t i = 0; i < words.size()-2; ++i)
        threeWords.push_back(words[i] + ' ' + words[i+1] + ' ' + words[i+2]);

    for(size_t i = 0; i < threeWords.size(); ++i)
        cout << i << ": " << threeWords[i] << endl;

    return 0;
}

The word splitting code is inspired by this post

Community
  • 1
  • 1
Antoine
  • 13,494
  • 6
  • 40
  • 52
  • hey antoine, can you elaborate more on what you mean by mixing integer indicies and iterators? i'm a noob. as you can probably tell from my code, i used brute force to perform the necessary output – user3239138 Mar 03 '14 at 17:07
  • 1
    @user3239138: For example, you use the same variable `it1` for different things: iterate on `oneWordPhrase` and `twoWordPhrase`. It obviously works just fine but as your code grows I really recommend using a variable for one purpose only. In your case, in the second loop you really don't need `it1` as you could have replaced `*it1` with `twoWordPhrase[i]` that's what I called integer indices. – Antoine Mar 03 '14 at 17:13
  • @user3239138: Since you're starting with C++ I edited my post with a (hopefully) more idiomatic code for your task, hope it helps – Antoine Mar 03 '14 at 17:49
  • now that i think about it, i wanted to use an iterator to keep count of when i'm about to reach to the end. hence, the if(it1==twoWordPhrase.end()-1). i couldn't think of a way to do that without an iterator. – user3239138 Mar 03 '14 at 17:52
  • No problem, don't forget to vote/accept helpful answers ;) Also note that if you had std::list instead of std::vector you'd be forced to use both an int to keep count and an iterator since on most containers you can't do iterator arithmetic (like `end()-1`). – Antoine Mar 03 '14 at 17:55