Re: [Flightgear-devel] STL help requested

2005-02-07 Thread David Luff
Christian Mayer writes:


> "The C++ Programming language 3rd ed." tells me:
> 
> Basically you've got 2 options:
> 
> 1 - create a class with the "<" operator
> class IACOcode
> {
>string the_code;
> }
> bool operator<( const IACOcode& a, const IACOcode& b )
> {
>   return your ordering;
> }
> map apt_map;
> 
> 
> 2 - create a custom sort order
> class IACOcode_compare
> {
> public:
>   bool operator()( const string& x, const string& y) const
>   {
> return your ordering;
>   }
> }
> map apt_map;
> 
> 
> Then you'll automatically get the desired result with your described lookup.
> 

Thanks to everyone who replied.  I can see how to do it now, but unfortuanately 
it's now been complicated by the fact that the GPS unit appears to sometimes 
consider letters before numbers (forward prediction of airports), but sometime 
consider numbers before letters (scanning through the waypoint lists).  It 
seems that associative containers need the comparison operator specified at 
creation (for good reason when I think about it) so I guess I'll just carry on 
with my hack to avoid storing the data in memory twice.

Cheers - Dave

___
Flightgear-devel mailing list
Flightgear-devel@flightgear.org
http://mail.flightgear.org/mailman/listinfo/flightgear-devel
2f585eeea02e2c79d7b1d8c4963bae2d


Re: [Flightgear-devel] STL help requested

2005-02-07 Thread Gerhard Wesp
>   bool operator()( const string& x, const string& y) const
>   {
> return your ordering;
>   }

Where your ordering can be written as

  std::lexicographical_compare
  ( x.begin() , x.end() , y.begin() , y.end() , ICAOcode_char_lt() )

where ICAOcode_char_lt implements the ``less than'' relation for the
individual characters for your ICAO codes:

struct ICAOcode_char_lt {

  bool operator()( char const x , char const y ) const {

// Numbers come after letters:
if( std::isalpha( x ) && std::isdigit( y ) ) { return true ; }

// Upper-case only comparison:
return std::toupper( x ) < std::toupper( y ) ;

  }

} ;

(hope this relation is transitive---please check!)

Cheers
-Gerhard
-- 
Gerhard Wesp o o   Tel.: +41 (0) 43 5347636
Bachtobelstrasse 56   |   http://www.cosy.sbg.ac.at/~gwesp/
CH-8045 Zuerich  \_/   See homepage for email address!

___
Flightgear-devel mailing list
Flightgear-devel@flightgear.org
http://mail.flightgear.org/mailman/listinfo/flightgear-devel
2f585eeea02e2c79d7b1d8c4963bae2d


Re: [Flightgear-devel] STL help requested

2005-02-07 Thread Gerhard Wesp
On Fri, Feb 04, 2005 at 11:37:54PM +0100, Erik Hofman wrote:
> You could use qsort to sort the map just prior to using it:

No you cannot, neither is this necessary. std::map<> is always
maintained in sorted order.  For this it uses the comparision function
std::less<> or the one given in the template argument.  See Christian
Mayer's mail for details.

I recommend Nicolai Josuttis' book:  The C++ standard library.  A
tutorial and reference.  He also mentions another technique which could
be used to achive the desired behaviour:  Defining your own char_traits<
char > class.  But IMO this is a bit awkward.

Cheers
-Gerhard
-- 
Gerhard Wesp o o   Tel.: +41 (0) 43 5347636
Bachtobelstrasse 56   |   http://www.cosy.sbg.ac.at/~gwesp/
CH-8045 Zuerich  \_/   See homepage for email address!

___
Flightgear-devel mailing list
Flightgear-devel@flightgear.org
http://mail.flightgear.org/mailman/listinfo/flightgear-devel
2f585eeea02e2c79d7b1d8c4963bae2d


Re: [Flightgear-devel] STL help requested

2005-02-05 Thread Paul Kahler
When you write your case-insensitive compare function
'0-9' are ascii 48-57
'a-z' are ascii 97-172
'A-Z' are ascii 65-90

by masking off the 32 bit, you make all letters upper case while moving
the numbers to the range 16-25. Now you want the numbers to come after
the letters, so you could toggle the 64 bit and get:
'0-9' = 80-89
'A-Z' = 1-26
'a-z' = 1-26

So if c is an ascii character, x = ((c & ~32)^64) would be a value that
compares with the properties you seek. You'll still need to write a
function to compare strings while using this character mapping.

Hope it helps,
Paul



___
Flightgear-devel mailing list
Flightgear-devel@flightgear.org
http://mail.flightgear.org/mailman/listinfo/flightgear-devel
2f585eeea02e2c79d7b1d8c4963bae2d


Re: [Flightgear-devel] STL help requested

2005-02-04 Thread Christian Mayer
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

David Luff schrieb:
> Hi folks,
> 
> I've run into a tricky problem when using stl map, and am hoping someone 
> might be able to point me on the right direction.
> 
> I have a map of airports, indexed by string, which is the ICAO code:
> 
> map apt_map;
> 
> Now, I want to emulate the 'search ahead' function of GPS code entry, so 
> that, for instance, entering "KC" will cause "KCAD" to be displayed - the 
> first airport in the database starting with "KC".  To do this I use the 
> lower_bound function, for both "KC" and "KD".  If the returned iterators 
> don't match, then there is a valid match for "KC".
> 
> map::iterator it1, it2;
> it1 = apt_map.lower_bound("KC");
> it2 = apt_map.lower_bound("KD");
> 
> return(it1 == it2 ? NULL : it1->second);
> 
> So far, so good.  Now, the problem is that the KLN89 (and probably most/all 
> GPS units) regards A->Z as coming before 0->9, whereas the standard string 
> compare function regards 0->9 as coming before A->Z.  So in this instance I 
> might get "KC52" displayed instead of "KCAD" (there isn't really a KC52, but 
> there are many examples outside the US where this bites).  
> 
> Now, I can get round this by using a comparison of lower_bound tests for 
> "KC", "KCA" and "KD", and it works.  Unfortunately I then have to check for 
> non-alpha chars down to the end of the returned string, and re-test any with 
> 'A' substituted in place.  It's effective, but really ugly!  I had to think 
> quite hard about code I only wrote a week ago to compose the last sentence, 
> and that's always a bad sign.  What I'm sure I ought to be able to do is to 
> define a custom comparison operator that performs a string comparison where 
> numbers are considered to come after letters, and for good measure to do a 
> case-insensitive match on the letters.  I want to be able to do something 
> like:
> 
> it1 = apt_map.lower_bound("KC", gps_less);
> 
> with all the ugly bits tucked away in gps_less which I can get working and 
> them forget about.  Unfortunately, I can't find any good example in any of my 
> books to do this, nor on the internet, and everything I try is giving me 
> swathes of typical gruesome-to-mentally-parse stl error messages.  If anyone 
> has an example of how to do this, or any pointers to one, I'd be most 
> grateful.

"The C++ Programming language 3rd ed." tells me:

Basically you've got 2 options:

1 - create a class with the "<" operator
class IACOcode
{
   string the_code;
}
bool operator<( const IACOcode& a, const IACOcode& b )
{
  return your ordering;
}
map apt_map;


2 - create a custom sort order
class IACOcode_compare
{
public:
  bool operator()( const string& x, const string& y) const
  {
return your ordering;
  }
}
map apt_map;


Then you'll automatically get the desired result with your described lookup.

CU,
Christian
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.0 (MingW32)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD8DBQFCBAAwlhWtxOxWNFcRAvoUAKCQmu/HJmzAQ6OZCLwCPJXoNLalPQCfSKB3
TBEVeGwmDCjOwegYbvbj8AQ=
=mohP
-END PGP SIGNATURE-

___
Flightgear-devel mailing list
Flightgear-devel@flightgear.org
http://mail.flightgear.org/mailman/listinfo/flightgear-devel
2f585eeea02e2c79d7b1d8c4963bae2d


Re: [Flightgear-devel] STL help requested

2005-02-04 Thread Erik Hofman
David Luff wrote:
Hi folks,
I've run into a tricky problem when using stl map, and am hoping someone might 
be able to point me on the right direction.
I have a map of airports, indexed by string, which is the ICAO code:
map apt_map;
Now, I want to emulate the 'search ahead' function of GPS code entry, so that, for instance, entering "KC" will cause 
"KCAD" to be displayed - the first airport in the database starting with "KC".  To do this I use the lower_bound 
function, for both "KC" and "KD".  If the returned iterators don't match, then there is a valid match for 
"KC".
map::iterator it1, it2;
it1 = apt_map.lower_bound("KC");
it2 = apt_map.lower_bound("KD");
return(it1 == it2 ? NULL : it1->second);
So far, so good.  Now, the problem is that the KLN89 (and probably most/all GPS units) regards A->Z as coming before 0->9, whereas the standard string compare function regards 0->9 as coming before A->Z.  So in this instance I might get "KC52" displayed instead of "KCAD" (there isn't really a KC52, but there are many examples outside the US where this bites).  
You could use qsort to sort the map just prior to using it:
http://www.cplusplus.com/ref/cstdlib/qsort.html
It requires a function that returns <0, 0 or >0 for every sort 
operation, so you can define the sorting algorithm yourself.

Erik
___
Flightgear-devel mailing list
Flightgear-devel@flightgear.org
http://mail.flightgear.org/mailman/listinfo/flightgear-devel
2f585eeea02e2c79d7b1d8c4963bae2d