Google
 
Webnews.only-4-geeks.com
Interesting places
news.only-4-geeks.com Forum Index » C++Goto page 1, 2  Next

Initialize one vector using elements in second vector...

 
Jump to:  
 
Peter Seidler
PostPosted: Fri Aug 22, 2008 1:01 pm    Post subject: Initialize one vector using elements in second vector...
       
Hi,
I have the following problem:

Given a vector: vec[10, 20, 30, 40, 50, 60]
and another one: idx[ 2, 3, 5]
I wish to generate a new vector based on the
elements in vec given by the indices in idx,
i.e. the result should be res[30, 40, 60].

Is there any way to accomplish this using the
STL vectors / algorithms.

I would like to do something like:
transform(idx.begin(), idx.end(),
back_inserter(res),
vec.at());
However this doesn't work.

Any suggestions?

--
Peter

--
[ See LINK for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

 
Guest
PostPosted: Sat Aug 23, 2008 11:58 pm    Post subject: Re: Initialize one vector using elements in second vector...
       
On Aug 22, 3:01 pm, Peter Seidler
<seidler@chem._INGEN_au_SPAM_.dk.sunsite.dk> wrote:
Quote:
Hi,
I have the following problem:

Given a vector: vec[10, 20, 30, 40, 50, 60]
and another one: idx[ 2, 3, 5]
I wish to generate a new vector based on the
elements in vec given by the indices in idx,
i.e. the result should be res[30, 40, 60].

Is there any way to accomplish this using the
STL vectors / algorithms.

I would like to do something like:
transform(idx.begin(), idx.end(),
back_inserter(res),
vec.at());
However this doesn't work.

Any suggestions?

Your idea is basically sound, but you can't pass member functions this
way. You need a binder, e.g. Boost.Bind or Std/TR1 bind.

#include <tr1/functional>

std::transform(idx.begin(), idx.end(), std::back_inserter(res),
std::tr1::bind(&std::vector<int>::at, vec, _1));

This might not work with this exact syntax, because at() is overloaded
on constness. It may have to look something like this:
static_cast<const int& (std::vector<int>::*)(typename
std::vector<int>::size_type) const>(&std::vector<int>::at)
I don't know the syntax for "pointer to const member function",
though.

Sebastian


--
[ See LINK for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

 
Guest
PostPosted: Sat Aug 23, 2008 11:58 pm    Post subject: Re: Initialize one vector using elements in second vector...
       
Quote:
Hi,
I have the following problem:

Given a vector: vec[10, 20, 30, 40, 50, 60]
and another one: idx[ 2, 3, 5]
I wish to generate a new vector based on the
elements in vec given by the indices in idx,
i.e. the result should be res[30, 40, 60].

Is there any way to accomplish this using the
STL vectors / algorithms.

I would like to do something like:
transform(idx.begin(), idx.end(),
back_inserter(res),
vec.at());
However this doesn't work.

Any suggestions?

std::transform(idx.begin(), idx.end(), std::back_inserter(res),
elem_by_index(vec));

Where Im using a unaryfunction called elem_by_index that saves a
reference to the backend vector, and simply returns the element
specified by the index

struct elem_by_index {
elem_by_index(std::vector<int> &v) : backend(v) {}
int operator()(int index) const{
return backend[index];
}

private:
std::vector<int> &backend;
};


--
[ See LINK for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

 
Christian Hackl
PostPosted: Sat Aug 23, 2008 11:58 pm    Post subject: Re: Initialize one vector using elements in second vector...
       
Peter Seidler wrote:

Quote:
Given a vector: vec[10, 20, 30, 40, 50, 60]
and another one: idx[ 2, 3, 5]
I wish to generate a new vector based on the
elements in vec given by the indices in idx,
i.e. the result should be res[30, 40, 60].

Is there any way to accomplish this using the
STL vectors / algorithms.

I would like to do something like:
transform(idx.begin(), idx.end(),
back_inserter(res),
vec.at());
t


You could accomplish it with the Boost Lambda Library. Here's an example:


typedef std::vector<int> Vector;

Vector::value_type const &(Vector::*at)(Vector::size_type) cons =
&Vector::at;

std::transform(idx.begin(), idx.end(), std::back_inserter(res),
bind(at, vec, _1));


The temporary variable "at" is used because the at() member function is
overloaded for const and non-const. See
LINK


--
Christian Hackl

[ See LINK for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

 
JSoft
PostPosted: Sat Aug 23, 2008 11:58 pm    Post subject: Re: Initialize one vector using elements in second vector...
       
On Fri, 22 Aug 2008 07:01:51 -0600, Peter Seidler wrote:

Quote:
Hi,
I have the following problem:

Given a vector: vec[10, 20, 30, 40, 50, 60] and another one: idx[ 2,
3, 5]
I wish to generate a new vector based on the elements in vec given by
the indices in idx, i.e. the result should be res[30, 40, 60].

Is there any way to accomplish this using the STL vectors / algorithms.

I would like to do something like:
transform(idx.begin(), idx.end(),
back_inserter(res),
vec.at());
However this doesn't work.

Any suggestions?

What's wrong with this?

typeof idx::iterator it;
typeof vec new_vec;

for (it = vec.begin(); it < vec.end(); ++it)
new_vec.push_back(vec[*it]);


Jake


--
[ See LINK for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

 
red floyd
PostPosted: Sat Aug 23, 2008 11:58 pm    Post subject: Re: Initialize one vector using elements in second vector...
       
On Aug 22, 6:01 am, Peter Seidler
<seidler@chem._INGEN_au_SPAM_.dk.sunsite.dk> wrote:
Quote:
Hi,
I have the following problem:

Given a vector: vec[10, 20, 30, 40, 50, 60]
and another one: idx[ 2, 3, 5]
I wish to generate a new vector based on the
elements in vec given by the indices in idx,
i.e. the result should be res[30, 40, 60].

Is there any way to accomplish this using the
STL vectors / algorithms.

I would like to do something like:
transform(idx.begin(), idx.end(),
back_inserter(res),
vec.at());
However this doesn't work.

Any suggestions?

How about something like:

struct converter {
const std::vector<int>& v;
converter(const std::vector<int>& v_) : v(v_) { }
converter(const converter& c) : v(c.v) { }
int operator()(int idx) const { return v.at(idx); }
};

std::transform(idx.begin(), idx.end(),
std::back_inserter(res),
converter(vec));


--
[ See LINK for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

 
uuilly
PostPosted: Sat Aug 23, 2008 11:58 pm    Post subject: Re: Initialize one vector using elements in second vector...
       
On Aug 22, 6:01 am, Peter Seidler
<seidler@chem._INGEN_au_SPAM_.dk.sunsite.dk> wrote:
Quote:
Hi,
I have the following problem:

Given a vector: vec[10, 20, 30, 40, 50, 60]
and another one: idx[ 2, 3, 5]
I wish to generate a new vector based on the
elements in vec given by the indices in idx,
i.e. the result should be res[30, 40, 60].

Is there any way to accomplish this using the
STL vectors / algorithms.

I would like to do something like:
transform(idx.begin(), idx.end(),
back_inserter(res),
vec.at());
However this doesn't work.

Any suggestions?

--
Peter



I always find that when you have to store indices, it's easiest to
just use a traditional for loop. Esp w/ vector.

Otherwise, the only way I can think to do it would be to use
boost::bind and the distance function acting on a reference from
idx.at. While it could probably be done I think it will look pretty
messy in the end. Though I would be keen on knowing an "STL way" of
doing this.


--
[ See LINK for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

 
Guest
PostPosted: Sat Aug 23, 2008 11:58 pm    Post subject: Re: Initialize one vector using elements in second vector...
       
On Aug 22, 9:01 am, Peter Seidler
<seidler@chem._INGEN_au_SPAM_.dk.sunsite.dk> wrote:
Quote:
Hi,
I have the following problem:

Given a vector: vec[10, 20, 30, 40, 50, 60]
and another one: idx[ 2, 3, 5]
I wish to generate a new vector based on the
elements in vec given by the indices in idx,
i.e. the result should be res[30, 40, 60].

Is there any way to accomplish this using the
STL vectors / algorithms.

I would like to do something like:
transform(idx.begin(), idx.end(),
back_inserter(res),
vec.at());
However this doesn't work.

Any suggestions?

--
Peter


#include "boost/functional.hpp" // boost::mem_fun_ref

// tr1::...

transform(
idx.begin( ),
idx.end( ),
res.begin( ),
boost::bind1st(
boost::mem_fun_ref<
int&,
vector< int, allocator<int> >,
size_t
Quote:
( &vector< int, allocator<int> >::at ), vec )
);


//...

no boost:

//...

using namespace std;

template<
typename From
Quote:

struct select_element_of

: public unary_function<
const typename From::size_type&,
void> {

explicit select_element_of( const From & from )
: from_( from ) {
}
operator const From ( ) {
return result_;
}
void operator ()( const typename From::size_type & val ) {
result_.push_back( from_[ val ] );
}

private:
const From & from_;
From result_;
};

res = for_each( idx.begin( ), idx.end( ), select_element_of< vector<
int > >( vec ) );

//...

cheers,
gil

--
[ See LINK for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

 
Greg Herlihy
PostPosted: Sat Aug 23, 2008 11:58 pm    Post subject: Re: Initialize one vector using elements in second vector...
       
On Aug 22, 6:01 am, Peter Seidler
<seidler@chem._INGEN_au_SPAM_.dk.sunsite.dk> wrote:
Quote:
I have the following problem:

Given a vector: vec[10, 20, 30, 40, 50, 60]
and another one: idx[ 2, 3, 5]
I wish to generate a new vector based on the
elements in vec given by the indices in idx,
i.e. the result should be res[30, 40, 60].

I would like to do something like:
transform(idx.begin(), idx.end(),
back_inserter(res),
vec.at());
However this doesn't work.


I think that you are on the right track. To complete the solution, I
would suggest something along these lines:

#include <iostream>
#include <iterator>
#include <algorithm>
#include <tr1/functional>
#include <vector>
#include <functional>

using std::tr1::placeholders::_1;
using std::tr1::bind;
using std::back_inserter;
using std::tr1::mem_fn;
using std::vector;

typedef vector<int> IntVector;

// declare an AtMemFunPtr member function pointer typedef
// for std::vector<int>::at() const

typedef IntVector::const_reference
(IntVector::*AtMemFunPtr)(IntVector::size_type) const;

const int va[] = { 10, 20, 30, 40, 50, 60 };
const int ia[] = { 2, 3, 5};

const int vaEnd = sizeof(va)/sizeof(va[0]);
const int iaEnd = sizeof(ia)/sizeof(ia[0]);

int main()
{
IntVector values( &va[0], &va[vaEnd] );
IntVector indexes( &ia[0], &ia[iaEnd] );

IntVector v; // holds output

std::transform( indexes.begin(), indexes.end(),
back_inserter(v),
bind( AtMemFunPtr(&IntVector::at), values,
_1));

std::cout << v[0] << "\n" << v[1] << "\n" << v[2] << "\n";
}

Program output:

30
40
60

Greg


--
[ See LINK for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

 
gast128@hotmail.com
PostPosted: Sat Aug 23, 2008 11:58 pm    Post subject: Re: Initialize one vector using elements in second vector...
       
Quote:
Hi,
I have the following problem:

Given a vector: vec[10, 20, 30, 40, 50, 60]
and another one: idx[ 2, 3, 5]
I wish to generate a new vector based on the
elements in vec given by the indices in idx,
i.e. the result should be res[30, 40, 60].

Is there any way to accomplish this using the
STL vectors / algorithms.

I would like to do something like:
transform(idx.begin(), idx.end(),
back_inserter(res),
vec.at());
However this doesn't work.

Any suggestions?

It is quite simple if you are not afraid of boost (or tr1):

#include <algorithm>
#include <iterator>
#include <vector>
#include <boost/bind.hpp>
#include <boost/assign/list_of.hpp>

void f()
{
typedef std::vector<int> int_vector;

int_vector vec = boost::assign::list_of(10)(20)(30)(40)(50)(60);
int_vector idx = boost::assign::list_of(2)(3)(5);

int_vector res;

std::transform(idx.begin(), idx.end(),
std::back_inserter(res),
boost::bind(&int_vector::at, &vec, _1));
}


--
[ See LINK for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

Page 1 of 2 .:. Goto page 1, 2  Next

Google
 
Webnews.only-4-geeks.com

Windows Update | C++ | C | PHP | JavaScript | Photoshop | Programming | Windows 2000 | Python | Windows XP | Object | Flash | Flash - ActionScript | Paint Shop Pro | Excel | PowerPoint | Access | Word | Windows 98 | Internet Explorer 6.0 | CorelDraw12 | Java | XML | asm x86 | Linux Mandrake | Linux RedHat | Outlook |  | news from newsgroups |_ | s

Web Templates

Awesome Website Templates ©

Tworzenie stron katowice ubezpieczenie oc medycyna estetyczna wrocław kupię mieszkanie oprocentowanie lokat