我想应该在不使用“for”循环和仅使用STL算法和迭代器的情况下编写下面的代码。如果我没有错,任何人都可以指导我如何做到这一点吗?
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);
答案 0 :(得分:4)
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);
现在编写自己的std::transform
版本,它具有三元函数:
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);
我猜你可以用C ++ 0x中的可变参数模板来获取transform_N
,但如果是这样我不知道它是什么,我从来没有使用它们。不确定你是否可以转发带有修改的可变数量的参数(在这种情况下,在每个参数周围包装* ++
)。
答案 1 :(得分:3)
你需要一点BOOST才能完成所有功能工作(或者自己制作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);
transform_3
函数可能如下所示:
// 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;
}
答案 2 :(得分:1)
为什么不将4个循环合并为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);
}
答案 3 :(得分:-1)
使用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;
}