STL算法和迭代器而不是“for”循环

时间:2011-02-23 19:38:28

标签: c++ stl

我想应该在不使用“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);

4 个答案:

答案 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;
}