STL algorithms and iterators instead of "for" loops

I suppose it should be somehow to write below a code snippet without using "for" loops and simply using STL algorithms and iterators. If I'm not mistaken, can someone advise me how to do this?

std::vector<double> A(N); std::vector<double> B(N); std::vector<double> C(N); std::vector<double> D(N); for(int i = 0; i < N; ++i) A[i] = myFunction1(i); for(int i = 0; i < N; ++i) B[i] = myFunction2(A[i], i); for(int i = 0; i < N; ++i) C[i] = myFunction3(A[i], B[i]); for(int i = 0; i < N; ++i) D[i] = myFunction4(A[i], B[i], i); 
+4
source share
4 answers
 typedef boost::counting_iterator<int> counter; std::transform(counter(0), counter(N), A.begin(), myFunction1); std::transform(A.begin(), A.end(), counter(0), B.begin(), myFunction2); std::transform(A.begin(), A.end(), B.begin(), C.begin(), myFunction3); 

Now write your own version of std::transform , which performs a triple function:

 template <typename In1, typename In2, typename In3, typename Out, typename FUNC> Out transform3(In1 first1, In1 last1, In2 first2, In3 first3, Out out, FUNC f) { while (first1 != last1) { *out++ = f(*first1++, *first2++, *first3++); } return out; } transform3(A.begin(), A.end(), B.begin(), counter(0), D.begin(), myFunction4); 

I think there might be something you can do with variable templates in C ++ 0x to get transform_N , but if so, I don't know what it is, I never used them. I'm not sure that you can redirect a variable number of arguments with modifications (in this case, wrapping * ++ around each of them, as it were).

+4
source

You will need a little BOOST to do all this with functional work (or create your own versions of boost :: counting_iterator)

 //for(int i = 0; i < N; ++i) // A[i] = myFunction1(i); std::transform( boost::counting_iterator<int>(0), boost::counting_iterator<int>(N), A.begin(), &myFunction1); //for(int i = 0; i < N; ++i) // B[i] = myFunction2(A[i], i); std::transform( A.begin(), A.end(), boost::counting_iterator<int>(0), B.begin(), &myFunction2); //for(int i = 0; i < N; ++i) // C[i] = myFunction3(A[i], B[i]); std::transform( A.begin(), A.end(), B.begin(), C.begin(), &myFunction3); // The STL doesn't have a version of transform that takes three inputs, but given a transform_3 that does: //for(int i = 0; i < N; ++i) // D[i] = myFunction4(A[i], B[i], i); transform_3( A.begin(), A.end(), B.begin(), boost::counting_iterator<int>(0), D.begin(), &myFunction4); 

This transform_3 function might look something like this:

 // Untested code template <class input1, class input2, class input3, class output, class oper> output transform_3 (input1 in1begin, input1 in1end, input2 in2, input3 in3, output out, oper op) { while (in1begin != in1end) *(out++) = op(*(in1begin++), *(in2++), *(in3++)); return out; } 
+3
source

Why not combine 4 loops into 1?

 for(int i = 0; i < N; ++i) { A[i] = myFunction1(i); B[i] = myFunction2(A[i], i); C[i] = myFunction3(A[i], B[i]); D[i] = myFunction4(A[i], B[i], i); } 
+1
source

Example using std::transform

 #include <algorithm> #include <vector> double myFunction1(int) { return 0; } double myFunction2(double, int) { return 1; } double myFunction3(double, double) { return 2; } double myFunction4(double, double, int) { return 3; } struct int_sequence { int_sequence(int i) : val(i) {} int_sequence operator++() { ++val; return *this; } int_sequence operator++(int) { return int_sequence(val++); } int operator*() const { return val; } bool operator!=(const int_sequence& other) const { return val != other.val; } private: int val; }; const size_t N = 100; int main(void) { std::vector<double> A(N); std::vector<double> B(N); std::vector<double> C(N); std::vector<double> D(N); //for(int i = 0; i < N; ++i) // A[i] = myFunction1(i); std::transform(int_sequence(0), int_sequence(N), A.begin(), &myFunction1); //for(int i = 0; i < N; ++i) // B[i] = myFunction2(A[i], i); std::transform(A.begin(), A.end(), int_sequence(0), B.begin(), &myFunction2); //for(int i = 0; i < N; ++i) // C[i] = myFunction3(A[i], B[i]); std::transform(A.begin(), A.end(), B.begin(), C.begin(), &myFunction3); for(int i = 0; i < N; ++i) D[i] = myFunction4(A[i], B[i], i); // there is no std::transform for three-argument functions (yet) return 0; } 
-1
source

Source: https://habr.com/ru/post/1341029/


All Articles