is there any transform_if algorithm?

Discussion in 'C++' started by baibaichen, Dec 15, 2005.

  1. baibaichen

    baibaichen Guest

    hi, i need to implement several functions which are similar with
    transform, but just oprerate on the elements that match some condition,
    i have wirtten one by myself:

    template<class In,class Out,class Pred class Op>
    Out transform_if(In first,In last,Out res,Pred p,Op op)
    {
    while(first!=last){
    if (p(*first))
    *res = op(*first);
    ++first;++res;
    }
    return res;
    }

    but it is something subtle:

    1). if the prediction return false? does output iterator increase?
    2). how about exception safe?
    3). efficiency problem, if we can predict the input will match the
    codition, then we have gotten the information that functor will do.

    my question is there any better way?
     
    baibaichen, Dec 15, 2005
    #1
    1. Advertising

  2. baibaichen

    Cy Edmunds Guest

    "baibaichen" <> wrote in message
    news:...
    > hi, i need to implement several functions which are similar with
    > transform, but just oprerate on the elements that match some condition,
    > i have wirtten one by myself:
    >
    > template<class In,class Out,class Pred class Op>
    > Out transform_if(In first,In last,Out res,Pred p,Op op)
    > {
    > while(first!=last){
    > if (p(*first))
    > *res = op(*first);
    > ++first;++res;
    > }
    > return res;
    > }
    >
    > but it is something subtle:
    >
    > 1). if the prediction return false? does output iterator increase?
    > 2). how about exception safe?
    > 3). efficiency problem, if we can predict the input will match the
    > codition, then we have gotten the information that functor will do.
    >
    > my question is there any better way?
    >


    I'm not sure what your function could do that can't be done with
    std::transform. Consider:

    class func
    {
    public:
    int operator () (int xj, int yj) const
    {
    if (xj == 2)
    return yj; // don't change the output value
    else
    return 2 * xj; // change the output value
    }
    };

    std::transform(x, x+3, y, y, func());

    does the same thing as:

    class pred
    {
    public:
    bool operator () (int xj) const {return xj != 2;}
    };

    class op
    {
    public:
    int operator () (int xj) const {return 2 * xj;}
    };

    template<class In,class Out,class Pred, class Op>
    Out transform_if(In first,In last,Out res,Pred p,Op op)
    {
    while(first!=last){
    if (p(*first))
    *res = op(*first);
    ++first;++res;
    }
    return res;
    }

    transform_if(x, x+3, y, pred(), op());

    The trick is to send the output stream to the functor along with the input
    stream.

    --
    Cy
    http://home.rochester.rr.com/cyhome/
     
    Cy Edmunds, Dec 15, 2005
    #2
    1. Advertising

  3. baibaichen

    baibaichen Guest

    no, it is TOTALly different when the Out template parameter is just
    output iterator,i.e. the insert_iterator and ostream_iterator, their
    oprerator++ do nothing!!

    here is "it is something subtle" in my previous post,i.e. if the
    prediction return false, does i need increase outpout iterator? it is
    diffcult to answser, consider:
    1. if the output equal input, i.e. i write back to input iterator, i
    need increase
    2. if output is a real iterator, such as a vector.begin() and that
    vector has enough space, i can not increase.
    3. if the ouput is something like insert_iterator or ostream_iterator,
    i do not care..

    the better way what i can image is the input template parameter is
    something like filter iterator, so we do not need tramsform_if, but i
    can not find any useful inforamtion about it.
     
    baibaichen, Dec 15, 2005
    #3
  4. baibaichen wrote:
    > hi, i need to implement several functions which are similar with
    > transform, but just oprerate on the elements that match some condition,
    > i have wirtten one by myself:
    >
    > template<class In,class Out,class Pred class Op>
    > Out transform_if(In first,In last,Out res,Pred p,Op op)
    > {
    > while(first!=last){
    > if (p(*first))
    > *res = op(*first);
    > ++first;++res;
    > }
    > return res;
    > }
    >
    > but it is something subtle:
    >
    > 1). if the prediction return false? does output iterator increase?
    > 2). how about exception safe?
    > 3). efficiency problem, if we can predict the input will match the
    > codition, then we have gotten the information that functor will do.
    >
    > my question is there any better way?


    Dunno if this will help you, but you can implement the transform_if in
    terms of remove_copy_if and for_each (or transform).
    Maybe this is the reason why there is no transform_if.

    --
    KM
     
    Augusto KhaoticMind da Silva, Dec 15, 2005
    #4
  5. baibaichen

    baibaichen Guest

    really? could u write more details?

    thanks
     
    baibaichen, Dec 15, 2005
    #5
  6. baibaichen

    Guest

    baibaichen wrote:
    > hi, i need to implement several functions which are similar with
    > transform, but just oprerate on the elements that match some condition,


    Check the VTL. It's a view library, and one of the components offers
    a filtered view over a collection. If you use that view as an input to
    transform,
    you're done. Another solution is to use an iterator wrapper around your
    output iterator that applies the transformation. Do both, and you can
    even
    use std::copy()

    HTH,
    Michiel Salters
     
    , Dec 15, 2005
    #6
  7. baibaichen

    Neil Cerutti Guest

    On 2005-12-15, baibaichen <> wrote:
    > no, it is TOTALly different when the Out template parameter is
    > just output iterator,i.e. the insert_iterator and
    > ostream_iterator, their oprerator++ do nothing!!


    That need not concern you. Algorithm transform will do the right
    thing. As long as the algorithm you're using accepts the type of
    iterator you pass in, all will be well.

    --
    Neil Cerutti
     
    Neil Cerutti, Dec 15, 2005
    #7
  8. baibaichen wrote:
    > really? could u write more details?
    >
    > thanks


    Supposing "p" is the predicate you want the elements to fulfill and
    "op" the operation you want to apply, you can write something like:


    remove_copy_if(iter1.begin(), iter1.end(), iter2.begin(), not1(op));
    transform(iter2.begin(), iter2.end(), iter2.begin(), p);


    The remove_copy_if will remove all elements from iter1 that do not
    match your predicate and copy them to iter2 (i.e., it will copy all
    elements that DO match your predicate).
    After that just execute transform on iter2 copying it to itself (hence
    why i said it maybe might be better to use for_each).


    --
    KM
     
    Augusto KhaoticMind da Silva, Dec 15, 2005
    #8
  9. baibaichen

    baibaichen Guest

    i have tested VTL before, but unfortunately , i can not compile it. :(
     
    baibaichen, Dec 16, 2005
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ahmed Moustafa
    Replies:
    0
    Views:
    817
    Ahmed Moustafa
    Nov 15, 2003
  2. david ullua
    Replies:
    9
    Views:
    1,493
    Stefan Ram
    Feb 5, 2007
  3. Replies:
    1
    Views:
    463
    Joe Seigh
    Dec 15, 2006
  4. zrebecca
    Replies:
    1
    Views:
    909
    zrebecca
    Mar 7, 2011
  5. zrebecca
    Replies:
    1
    Views:
    400
    zrebecca
    Mar 7, 2011
Loading...

Share This Page