Re: [Flightgear-devel] STL help requested
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
> 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
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
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
-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
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