2011-02-23 66 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