Re: Alternative STL Structure?
On 1 Dic, 05:01, Ian Collins <ian-n...@hotmail.com> wrote:
On 12/ 1/10 04:52 PM, Mike Copeland wrote:
In article<278d307f-721a-453d-a36d-4a0903e6ca33
@d8g2000yqf.googlegroups.com>, james.ka...@gmail.com says...
I have the following data structure that is currently process=
ed by an
STL map.
Although it currently works for most storage and retrieval, I=
have
need to process the data in different orders than the map key (teamNa=
me,
teamTypeCode). Knowing that I can't "resort" the data in an STL ma=
p, is
there another STL structure that I could use to store, sort, retrieve
and process the data defined in this structure? TIA
(Please don't criticize my naming conventions - I'm old and I=
prefer
this nomenclature...)
struct TEAMMAPTYPE
{ =
// Team Ids, Names
string teamCode; // Team Code =
(map key)
string teamName; // Team's Nam=
e
flag
char teamTypeCode; // Team type Co=
de
int teamMembers1; // Count of T=
eam Members-1
int teamMembers2; // Count of T=
eam Members-2} extern teamWork; // storage =
for Team info
typedef map<string, TEAMMAPTYPE> TEAMS;
TEAMS teamMap;
map<string, TEAMMAPTYPE>::iterator teamIt;
In addition to the other suggestions... Have you considered
using several std::set<TEAMMAPTYPE*,Compare>, with different
Compare?
No, and I don't know what that is. How would it help me, and=
how
would it work? I need to access that stiructure's data is several
different orders (teamCode, teamName, teamTypeCode), but the map object=
s
are available to me only in the teamCode fields order. Please explai=
n
how the std::set could achieve this. TIA
What James is suggesting is a group of sets with different sorting
orders. All you have to do is declare the comparison objects. For
example (untested):
struct ByTeamName
{
bool operator()( const TEAMMAPTYPE& lhs, const TEAMMAPTYPE& rhs )
{
return lhs.teamName < lhs.teamName;
}
};
std::set<TEAMMAPTYPE*,ByTeamName> teamsByTeamName;
Man I hate those all caps types!
--
Ian Collins
Hi again,
the example I posted before had a tricky problem. Corrected.
Hope it helps.
Francesco
// CODE
#include <set>
#include <iostream>
#include <iomanip>
//----------------------------------------------------------------------
class CData
{
public:
int m1;
int m2;
int m3;
// normal "full" ordering
// notice m3 is not taken into account
bool operator<( CData const & inObj ) const
{ return m1 < inObj.m1 ? true :
inObj.m1 < m1 ? false :
m2 < inObj.m2 ? true : false; }
};
std::ostream & operator<<( std::ostream & inStream,
CData const & inData )
{
return inStream << std::setw( 4 ) << inData.m1 << " "
<< std::setw( 4 ) << inData.m2 << " "
<< std::setw( 4 ) << inData.m3 << std::endl;
}
typedef std::multiset< CData > CMasterSet;
typedef CMasterSet::iterator CMasterIter;
//----------------------------------------------------------------------
template< typename T, T CData::*KPtr >
struct CIterComp
{
// custom ordering giving priority to one member
// then taking into account normal ordering
bool operator()( CMasterIter const & in1,
CMasterIter const & in2 ) const
{ return ( ( *in1 ).*KPtr ) < ( ( *in2 ).*KPtr ) ? true :
( ( *in2 ).*KPtr ) < ( ( *in1 ).*KPtr ) ? false :
*in1 < *in2; }
};
typedef std::multiset< CMasterIter,
CIterComp< int, &CData::m2 > >
CSlaveSet2;
typedef std::multiset< CMasterIter,
CIterComp< int, &CData::m3 > >
CSlaveSet3;
//----------------------------------------------------------------------
int main()
{
CMasterSet masterSet;
CSlaveSet2 slaveSet2;
CSlaveSet3 slaveSet3;
// populate
for( int c = 0; c < 15; ++c )
{
CData data;
data.m1 = static_cast< double >( rand() ) / RAND_MAX * 20;
data.m2 = static_cast< double >( rand() ) / RAND_MAX * 20;
data.m3 = static_cast< double >( rand() ) / RAND_MAX * 20;
CMasterIter iter = masterSet.insert( data );
slaveSet2.insert( iter );
slaveSet3.insert( iter );
}
// erasing is tricky
{
CData dummy;
dummy.m1 = 10;
CMasterIter iter = masterSet.lower_bound( dummy );
// suppose you have an iterator into the master set
// you want to erase THAT item from all sets
// doing slaveSet2.erase( iter ) might not do what you want
// while std::find will use equality comparison
// between iterators
// ah... erase first from slaves or else... UB
slaveSet2.erase(
std::find( slaveSet2.lower_bound( iter ),
slaveSet2.end(), iter ) );
slaveSet3.erase(
std::find( slaveSet3.lower_bound( iter ),
slaveSet3.end(), iter ) );
masterSet.erase( iter );
}
// DEFAULT ORDERING
for( CMasterIter iter = masterSet.begin();
iter != masterSet.end(); ++iter )
std::cout << *iter;
std::cout << std::string( 20, '-' ) << std::endl;
// SECOND ORDERING
for( CSlaveSet2::iterator iter = slaveSet2.begin();
iter != slaveSet2.end(); ++iter )
std::cout << **iter;
std::cout << std::string( 20, '-' ) << std::endl;
// THIRD ORDERING
for( CSlaveSet3::iterator iter = slaveSet3.begin();
iter != slaveSet3.end(); ++iter )
std::cout << **iter;
}
// END CODE