Reputation: 207
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
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
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
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