AlexGreat
AlexGreat

Reputation: 207

Assign int value to vector using iterator

I'm sitting on a small exercise in C++ Primer (3.23) for almost 2 days. I've tried many ways of assigning a value to vector<int>. I'll give you an actual exercise on which I work and code with which I came so far, but its totally wrong. I did a lot of research but found nothing useful.

Write a program to create a vector with 10 int elements. Using an iterator, assign each element a value that is twice its current value. Test the program by printing vector

And this is my code

int main(){  
vector<int> num(10);

for (auto it=num.begin();it != num.end() ;++it)//iterating through each element in vector 
{
    *it=2;//assign value to vector using iterator
    for (auto n=num.begin() ;n!=num.end();++n)//Iterating through existing elements in vector 
    {   
        *it+=*n;// Compound of elements from the first loop and 2 loop iteration
    }    
    cout<<*it<<" ";
}

keep_window_open("~");
return 0;
}  

My problem is I don't know how to assign an int value to each vector element using an iterator (I did to 1 but not to the five elements)! In addition I was breaking my head on how to do this exercise with 10 elements in vector, to each element must be a different value and an iterator must do the assignment.
Thank you for your time.

Upvotes: 12

Views: 36278

Answers (3)

zerocukor287
zerocukor287

Reputation: 1073

Here's my two cents about the topic.
Assume, the first element is 5, and we want to fill the rest.

We can go different ways, for example accessing the previous (or next) element. Because vector's elements are placed sequentially we can use for example the index to access elements, with operator[].

The most naive implementation (without iterators) we could come up is to access each element by the index, while skipping the first element (we take it granted, that it has some value)

#include <iostream>
#include <vector>

using namespace std;

int main()
{  
    vector<int> num(10);
    num[0] = 5;

    for (size_t i = 1; i < num.size(); i++)
    {
        num[i] = num[i - 1] * 2;
        cout << num[i] << ", ";
    }
}

Possible output is:

10, 20, 40, 80, 160, 320, 640, 1280, 2560, 

If we refine this a bit using iterators, we might end up the following code:

#include <iostream>
#include <vector>

using namespace std;

int main()
{  
    vector<int> num(10);
    num[0] = 5;

    auto iter = num.begin() + 1;
    auto end = num.end();
    for(; iter < end; iter++)
    {
        *iter = *std::prev(iter) * 2;
        cout << *iter << ", ";
    }
}

It does the same as before (resulting the same output) - staring at the 2nd element, and accessing the previous element. Only this time we are using the std::prev function.


On the other hand, if we can make a stateful function (storing the previous value), then we can achieve the same differently:

#include <iostream>
#include <vector>

using namespace std;

int main()
{  
    vector<int> num(10);
    num[0] = 5;

    int n = num[0];

    for (auto& element : num)
    {
        element = n;
        n *= 2;
        cout << element << ", ";
    }
}

Here, I am using a range-based for loop. Save the first element's value in a variable, and use that when calculating the other values. Pay attention that element is an auto& (reference). If it would be a plain value (auto without the reference), then you would modify a copy of your element.

Good thing of this version, that it is less error prone for array bounds (as it doesn't need the +/-1 at begin or end). However, it re-assigns the value of the first element without modifying it.


Finally, we could use the std::transform to transform a part of the array.

#include <iostream>
#include <vector>
#include <algorithm>

int main()
{  
    vector<int> num(10);
    num[0] = 5;
    
    std::transform(num.cbegin(), num.cend() - 1,  // iterate over the array, except the last
      num.begin() + 1,     // setting the "next" element
      [](int element1){    // lambda, that returns the new value
        return element1 * 2;
    });
    
    // print the whole vector
    for(auto i : num){
        cout << i << ", ";
    }
}

What I'm doing now, is to iterate over the same array using the std::transform, from the beginning, until just before the last element (so for the first 9 elements in a 10 element array), meanwhile setting the exact same array's next element (technically, the last 9 elements).
In the lambda I "transform" the previous element by multiplying with 2.

The result is the same as before:

5, 10, 20, 40, 80, 160, 320, 640, 1280, 2560,  

Upvotes: 0

Sonic Atom
Sonic Atom

Reputation: 446

Here's a much cleaner version of the accepted answer, using the concept of incrementing the iterator instead of a for loop:

#include <iostream>
#include <vector>

using namespace std;

int main()
{  
    vector<int> num(10);

    int n = 1;
    vector<int>::iterator it = num.begin();
    vector<int>::iterator itEnd = num.end();

    while (it != itEnd)
    {
        *it = n = n*2;
        cout << *it << " ";
        it++;
    }
}

Upvotes: 11

fatihk
fatihk

Reputation: 7929

You can do like this:

#include <iostream>
#include <vector>

using namespace std;

int main(){  

    vector<int> num(10);

    int initial_value = 2;
    *num.begin() = initial_value;
    cout<<*num.begin()<<" ";
    for (std::vector<int>::iterator it=num.begin()+1; it != num.end() ;++it)//iterating thru each elementn in vector 
    {
        *it=*(it-1) * 2;//assign value wtih 2 times of previous iterator

        cout<<*it<<" ";
    }

    return 0;
}

You just need to give some initial value to the first iterator and the rest is calculated in a for loop

Upvotes: 6

Related Questions