I plan to execute an operation on each data of a std::vector array as the following codes show:
std::vector<int> abc;
abc.push_back(1);
abc.push_back(5);
abc.push_back(2);
std::sort(abc);
int min = abc[0];
int max = abc[2];
for(int i=0; i<3; i++)
abc[i] = (abc[i]-min)/(max-min);
The question I have now is that whehter I have more elegant way of performing
for(int i=0; i<3; i++)
abc[i] = (abc[i]-min)/(max-min)
with for_each , trasnform
or other methods in stl. The difficulty I have with these functions lies in the fact that I do not know how to incorporate external parameters within them.
Here is an example that uses for_each
to update each element in abc
:
std::for_each(abc.begin(), // Start of range
abc.end(), // End of range
[=](int &value) // The operation to apply
{
value=(value-min)/(max-min);
});
Changing the sequence being iterated over by for_each
is often frowned upon, despite the fact that for_each
guarantees the order of traversal as well as how many invocations occur per element. However, to appease the naysayers, you may want to use transform
instead which has no such guarantees (neither of the order of traversal nor of the number of calls of the predicate other than via a complexity guarantee {Note: the complexity has been modified to a guarantee of the number of calls in C++11, see 25.3.4.4}):
std::transform(abc.begin(), // Start of source range
abc.end(), // End of source range
abc.begin(), // Start of destination range
[=](int value) // The operation to apply
{
return (value-min)/(max-min);
});
By the way, since you're doing integer division in your formula, you have to be very careful with the truncation of the result. You should probably check for a divide by zero, as well.
With C++11 you could use a lambda that captures the needed variables:
std::transform(std::begin(abc), std::end(abc),
std::begin(abc),
[=](int x) { return (x-min)/(max-min); });
This is equivalent to your loop, although you might want to verify whether the logic was correct in the first place.
This is easily achieved using std::transform
and a suitable functor. Here, a lambda is used for brevity:
std::transform(std::begin(abc),
std::end(abc),
std::begin(abc),
[&](int i) { return (i-min)/(max-min); });
It isn't clear whether this is an improvement. I would just write a plain range-based loop:
for(int& i : abc)
i = (i-min)/(max-min);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.