Problem with iterators

closed account (EwCjE3v7)
Okay so I was wondering if there is a way to return a incremented iterator but now increment it. Let me clear this up a little.
So this is what I have written by using indexes instead of iterators.
It counts the amount of times a duplicated word comes beside itself
Such as
input: how now now now brown cow cow
out: now occurred 3 times.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
// Keyboard keys \ |
#include <iostream>
#include <string>
#include <vector>
using std::cout; using std::endl; using std::cin;
using std::string; using std::vector;

int main()
{
    string input; // for getting input
    vector<string> words; // for storing our input
    cout << "This program will find duplicated words that are beside each other.\nType words, once finished press CTRL+Z/D (Windows/Unix) " << endl;

    while (cin >> input) { // get input until we hit end-of-file
        words.push_back(input); // store that input in a vector called word
    }

    unsigned counter = 0, finalCnt = 0;
    string word;

    for (unsigned index = 0; index != words.size() - 1; ++index) {
        if (words[index] == words[index + 1]) {
            ++counter;
            if (counter >= finalCnt && counter == 1) {
                finalCnt = 2;
                word = words[index];
            }
            else if (counter >= finalCnt) {
                ++finalCnt;
                word = words[index];
            }
        } else {
            counter = 0;
        }
    }

    if (finalCnt != 1) {
        cout << word << " occurred " << finalCnt << " times." << endl;
    } else {
        cout << "There were no duplicate words" << endl;
    }

    return 0;
}


I`m trying to right that with iterators.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
// Keyboard keys \ |
#include <iostream>
#include <string>
#include <vector>
using std::cout; using std::endl; using std::cin;
using std::string; using std::vector;

int main()
{
    string input; // for getting input
    vector<string> words; // for storing our input
    cout << "This program will find duplicated words that are beside each other.\nType words, once finished press CTRL+Z/D (Windows/Unix) " << endl;

    while (cin >> input) { // get input until we hit end-of-file
        words.push_back(input); // store that input in a vector called word
    }

    unsigned counter = 0, finalCnt = 0;
    string word;

    for (auto beg = words.cbegin(); beg != words.cend() - 1; ++beg) {
        auto secondWord = beg;
        ++secondWord;
        if (*beg == *secondWord) {
            ++counter;
            if (counter >= finalCnt && counter == 1) {
                finalCnt = 2;
                word = *beg;
            }
            else if (counter >= finalCnt) {
                ++finalCnt;
                word = *beg;
            }
        } else {
            counter = 0;
        }
    }

    if (finalCnt != 1) {
        cout << word << " occurred " << finalCnt << " times." << endl;
    } else {
        cout << "There were no duplicate words" << endl;
    }

    return 0;
}

As you can see I have another iterator declared(secondWord). Is there a way I can do that without secondWord.
like this wont work
if (*beg == *++beg)

as its incrementing beg. I would like to dereference the next word but not advance beg.

Thank you
You can always write

if (*beg == *(beg + 1))

for random access iterators, or if you cannot guarantee that,

if (*beg == *next( beg ))


That said, there's nothing wrong with using a pair of iterators:

1
2
3
4
for (auto a, b = words.cbegin(), a = b++; b != words.cend(); a = b++)
{
    if (*a == *b) ...
}

(or something similar)

There are also prepackaged solutions to this... but I presume that is not what you wish...

Hope this helps.
Another thing to mention if it isn't a random access iterator you can also use std::advance http://www.cplusplus.com/reference/iterator/advance/

Yes, but std::advance() wouldn't be any less unwieldly than his current code. std::next() does exactly what he wants.
closed account (EwCjE3v7)
Thank you guys, I tried *beg + 1 without () and got an error. Thanks that did the trick
What exactly does std::advance do. Like does it make a temp iterator?
Read the docs.

advance( i )    ==    i = i + 1
next( i )    ==    (i + 1)
closed account (EwCjE3v7)
oh okay, Thank you Duoas

advance is kind of the same as mine than
std::next() does exactly what he wants.
Sorry I didn't read
I would like to dereference the next word but not advance beg.
I was thinking he wanted to do it at the same time. Also to further duaos post.

They look something like this when they are not random-access iterators. Otherwisestd::advance simply does it = it + n;

1
2
3
4
5
6
7
8
9
10
11
12
template<class ForwardIt>
ForwardIt next(ForwardIt it, typename std::iterator_traits<ForwardIt>::difference_type n = 1)
{
    std::advance(it, n);
    return it;
}

template<class ForwardIt>
void advance(ForwardIt &it, typename std::iterator_traits<ForwardIt>::difference_type n = 1)
{
    for(auto i = 0; i < n; ++i) ++it;
}
Topic archived. No new replies allowed.