2011-02-23 91 views
4

我想应该有一些不使用“for”循环和仅使用STL算法和迭代器来编写下面的代码段。如果我没有错,任何人都可以指导我如何做到这一点?STL算法和迭代器,而不是“for”循环

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); 
+1

对于它的价值,STL算法往往不lambda表达式使用跳动。你的编译器是否支持lambda表达式? – 2011-02-23 19:41:05

+0

@ james-mcnellis我使用GCC,但我不知道什么是lambda表达式。 – 2011-02-23 19:44:24

+0

你可以先看看std :: transform和std :: for_each – Erik 2011-02-23 19:46:36

回答

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

为什么不将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); 
} 
+0

老兄,这不是我的问题,它应该清楚为什么我分别写他们 – 2011-02-23 19:46:27

+5

@开始 - 它不清楚为什么你有它分开。 – 2011-02-23 19:48:07

+0

@ daniel-a-white因为我在问一个问题,而不是编写实际的代码,所以我试图展示不同的单独场景,我猜想这些案例应该有不同的答案。然后我会期待一个答案,比如“你可以为第一个循环写这个,但是它不可能在第四个循环中”。现在清除? – 2011-02-23 19:53:54

3

你需要一点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; 
} 
-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; 
} 
+0

downvote的原因? – 2011-02-25 02:08:34