Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #13917 > unrolled thread
| Started by | Rui Maciel <rui.maciel@gmail.com> |
|---|---|
| First post | 2012-02-11 21:44 +0000 |
| Last post | 2012-02-12 18:48 +0000 |
| Articles | 15 — 9 participants |
Back to article view | Back to comp.lang.c++
std::map: best way to get biggest key? Rui Maciel <rui.maciel@gmail.com> - 2012-02-11 21:44 +0000
Re: std::map: best way to get biggest key? Leigh Johnston <leigh@i42.co.uk> - 2012-02-11 21:57 +0000
Re: std::map: best way to get biggest key? Rui Maciel <rui.maciel@gmail.com> - 2012-02-11 22:09 +0000
Re: std::map: best way to get biggest key? "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> - 2012-02-11 23:28 +0100
Re: std::map: best way to get biggest key? Rui Maciel <rui.maciel@gmail.com> - 2012-02-12 15:07 +0000
Re: std::map: best way to get biggest key? Dombo <dombo@disposable.invalid> - 2012-02-12 17:00 +0100
Re: std::map: best way to get biggest key? "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> - 2012-02-12 18:41 +0100
Re: std::map: best way to get biggest key? Ian Collins <ian-news@hotmail.com> - 2012-02-13 07:13 +1300
Re: std::map: best way to get biggest key? Jorgen Grahn <grahn+nntp@snipabacken.se> - 2012-02-12 19:40 +0000
Re: std::map: best way to get biggest key? Joshua Maurice <joshuamaurice@gmail.com> - 2012-02-12 13:25 -0800
Re: std::map: best way to get biggest key? Dombo <dombo@disposable.invalid> - 2012-02-11 23:29 +0100
Re: std::map: best way to get biggest key? Paavo Helde <myfirstname@osa.pri.ee> - 2012-02-11 16:39 -0600
Re: std::map: best way to get biggest key? Rui Maciel <rui.maciel@gmail.com> - 2012-02-12 15:16 +0000
Re: std::map: best way to get biggest key? Goran <goran.pusic@gmail.com> - 2012-02-12 08:41 -0800
Re: std::map: best way to get biggest key? Leigh Johnston <leigh@i42.co.uk> - 2012-02-12 18:48 +0000
| From | Rui Maciel <rui.maciel@gmail.com> |
|---|---|
| Date | 2012-02-11 21:44 +0000 |
| Subject | std::map: best way to get biggest key? |
| Message-ID | <jh6nft$43f$1@speranza.aioe.org> |
The typical way to get the biggest key of a std::map is to rely on the default sorting for std::map (based on std::less) and simply check the key of the last element of a map, as: <code> std::map<key,value> my_map; //... key largest_key = my_map.rbegin()->first <code> Yet, this trick is a bit flimsy and isn't very elegant. Does anyone know if there is a better way to extract the biggest key of a std::map? Thanks in advance, Rui Maciel
[toc] | [next] | [standalone]
| From | Leigh Johnston <leigh@i42.co.uk> |
|---|---|
| Date | 2012-02-11 21:57 +0000 |
| Message-ID | <JvOdnamUgb3OeavSnZ2dnUVZ8tydnZ2d@giganews.com> |
| In reply to | #13917 |
On 11/02/2012 21:44, Rui Maciel wrote: > The typical way to get the biggest key of a std::map is to rely on the > default sorting for std::map (based on std::less) and simply check the key > of the last element of a map, as: > > <code> > std::map<key,value> my_map; > //... > key largest_key = my_map.rbegin()->first > <code> > > > Yet, this trick is a bit flimsy and isn't very elegant. Does anyone know if > there is a better way to extract the biggest key of a std::map? Why do you think it is a "trick"? Why do you think it is a "bit flimsy"? Why do you think it "isn't very elegant"? /Leigh
[toc] | [prev] | [next] | [standalone]
| From | Rui Maciel <rui.maciel@gmail.com> |
|---|---|
| Date | 2012-02-11 22:09 +0000 |
| Message-ID | <jh6ov5$7am$1@speranza.aioe.org> |
| In reply to | #13919 |
Leigh Johnston wrote: > Why do you think it is a "trick"? Why do you think it is a "bit > flimsy"? Why do you think it "isn't very elegant"? It requires that the key comparison function used in a map sorts the keys in such a way that the last key/value pair includes the biggest key. If a map is created with some other key comparison function then this trick fails. Rui Maciel
[toc] | [prev] | [next] | [standalone]
| From | "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> |
|---|---|
| Date | 2012-02-11 23:28 +0100 |
| Message-ID | <jh6q2b$p6h$1@dont-email.me> |
| In reply to | #13922 |
On 11.02.2012 23:09, Rui Maciel wrote: > Leigh Johnston wrote: > >> Why do you think it is a "trick"? Why do you think it is a "bit >> flimsy"? Why do you think it "isn't very elegant"? > > It requires that the key comparison function used in a map sorts the keys in > such a way that the last key/value pair includes the biggest key. If a map > is created with some other key comparison function then this trick fails. If you want the key that is largest according to to some other ordering than the map's, then you have no option but to check all keys. The map cannot magically know what other ordering you have in mind. I would think that that should be, like, *obvious*? Cheers & hth., - Alf
[toc] | [prev] | [next] | [standalone]
| From | Rui Maciel <rui.maciel@gmail.com> |
|---|---|
| Date | 2012-02-12 15:07 +0000 |
| Message-ID | <jh8kij$5gb$1@speranza.aioe.org> |
| In reply to | #13925 |
Alf P. Steinbach wrote: > If you want the key that is largest according to to some other ordering > than the map's, then you have no option but to check all keys. > > The map cannot magically know what other ordering you have in mind. > > I would think that that should be, like, *obvious*? You missed the point, or you let your need to post petty comments get the best of you. No one asked about magic, or questioned that algorithms are needed to perform any computation ono a computer. I don't know how or why you reached that conclusion. The question, which you failed read or understand, was if there was a better way to extract the biggest key of a std::map. To put it more clearly, the question was if there was any standard way (that is, employing components from the STL) that made it possible to extract the biggest key from a std::map, without relying on the key comparison function used by an std::map object. Rui Maciel
[toc] | [prev] | [next] | [standalone]
| From | Dombo <dombo@disposable.invalid> |
|---|---|
| Date | 2012-02-12 17:00 +0100 |
| Message-ID | <4f37e1e9$0$14711$5fc3050@news.tiscali.nl> |
| In reply to | #13938 |
Op 12-Feb-12 16:07, Rui Maciel schreef: > Alf P. Steinbach wrote: > >> If you want the key that is largest according to to some other ordering >> than the map's, then you have no option but to check all keys. >> >> The map cannot magically know what other ordering you have in mind. >> >> I would think that that should be, like, *obvious*? > > You missed the point, or you let your need to post petty comments get the > best of you. > > No one asked about magic, or questioned that algorithms are needed to > perform any computation ono a computer. I don't know how or why you reached > that conclusion. > > The question, which you failed read or understand, was if there was a better > way to extract the biggest key of a std::map. To put it more clearly, the > question was if there was any standard way (that is, employing components > from the STL) that made it possible to extract the biggest key from a > std::map, without relying on the key comparison function used by an std::map > object. You could take a look at std::max_element() in <algorithm> which allows you to pass your own comparison function/functor. Keep in mind that std::max_element() has linear complexity; it has to go through all elements in the map so it is no faster than just iterating over a std::map.
[toc] | [prev] | [next] | [standalone]
| From | "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> |
|---|---|
| Date | 2012-02-12 18:41 +0100 |
| Message-ID | <jh8tl0$u8s$1@dont-email.me> |
| In reply to | #13938 |
On 12.02.2012 16:07, Rui Maciel wrote: > Alf P. Steinbach wrote: > >> If you want the key that is largest according to to some other ordering >> than the map's, then you have no option but to check all keys. >> >> The map cannot magically know what other ordering you have in mind. >> >> I would think that that should be, like, *obvious*? > > You missed the point, or you let your need to post petty comments get the > best of you. > > No one asked about magic, or questioned that algorithms are needed to > perform any computation ono a computer. I don't know how or why you reached > that conclusion. > > The question, which you failed read or understand, was if there was a better > way to extract the biggest key of a std::map. To put it more clearly, the > question was if there was any standard way (that is, employing components > from the STL) that made it possible to extract the biggest key from a > std::map, without relying on the key comparison function used by an std::map > object. Well, if you want the key that is largest according to to some other ordering than the map's, i.e. that is largest according to some other key comparision function that the map's, then you have no option but to check all keys. Unless you have additional information about the keys, of course. The map cannot magically know what other ordering you have in mind: it cannot know the other key comparision function that you mean when you say "biggest". I still would think that that should be, like, *obvious*? Sorry about the perceived pettiness. It was not meant to elevate myself relative to you. It was and is meant to slap the horse's behind so that it moves forward, or in other words, start *thinking*, he he :-) . Cheers & hth., - Alf
[toc] | [prev] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2012-02-13 07:13 +1300 |
| Message-ID | <9pqdqbFrknU1@mid.individual.net> |
| In reply to | #13938 |
On 02/13/12 04:07 AM, Rui Maciel wrote: > > The question, which you failed read or understand, was if there was a better > way to extract the biggest key of a std::map. To put it more clearly, the > question was if there was any standard way (that is, employing components > from the STL) that made it possible to extract the biggest key from a > std::map, without relying on the key comparison function used by an std::map > object. The key comparison function used by std::map defines "Biggest" in the context of that map. -- Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | Jorgen Grahn <grahn+nntp@snipabacken.se> |
|---|---|
| Date | 2012-02-12 19:40 +0000 |
| Message-ID | <slrnjjg5d7.1ls.grahn+nntp@frailea.sa.invalid> |
| In reply to | #13938 |
On Sun, 2012-02-12, Rui Maciel wrote: ... > The question, which you failed read or understand, was if there was a better > way to extract the biggest key of a std::map. To put it more clearly, the > question was if there was any standard way (that is, employing components > from the STL) that made it possible to extract the biggest key from a > std::map, without relying on the key comparison function used by an std::map > object. I still get the feeling that you see the ordering of entries in a std::map as an implementation detail which you aren't meant to exploit. If so, that's a misunderstanding -- the ordering is a vital aspect of std::map. (And now that we have std::unordered_map that's maybe clearer than it used to be.) If you do this a lot, it's probably a good idea to implement template<class Key, class V> Key largest_key(const std::map<Key, V>&); and use that. /Jorgen -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o .
[toc] | [prev] | [next] | [standalone]
| From | Joshua Maurice <joshuamaurice@gmail.com> |
|---|---|
| Date | 2012-02-12 13:25 -0800 |
| Message-ID | <e93f154f-7625-47c4-b7c8-5c9c57eb7376@s8g2000pbj.googlegroups.com> |
| In reply to | #13938 |
On Feb 12, 7:07 am, Rui Maciel <rui.mac...@gmail.com> wrote: > Alf P. Steinbach wrote: > > If you want the key that is largest according to to some other ordering > > than the map's, then you have no option but to check all keys. > > > The map cannot magically know what other ordering you have in mind. > > > I would think that that should be, like, *obvious*? > > You missed the point, or you let your need to post petty comments get the > best of you. > > No one asked about magic, or questioned that algorithms are needed to > perform any computation ono a computer. I don't know how or why you reached > that conclusion. > > The question, which you failed read or understand, was if there was a better > way to extract the biggest key of a std::map. To put it more clearly, the > question was if there was any standard way (that is, employing components > from the STL) that made it possible to extract the biggest key from a > std::map, without relying on the key comparison function used by an std::map > object. So, given a map, and a different sorting criterion, you want the biggest key of the map under the new sorting criterion. Iterate over all the keys, keeping track of the "biggest thus far". std::for_each may be useful in that regard with lambda functions, but I would just write the loop myself.
[toc] | [prev] | [next] | [standalone]
| From | Dombo <dombo@disposable.invalid> |
|---|---|
| Date | 2012-02-11 23:29 +0100 |
| Message-ID | <4f36eb9e$0$14708$5fc3050@news.tiscali.nl> |
| In reply to | #13922 |
Op 11-Feb-12 23:09, Rui Maciel schreef: > Leigh Johnston wrote: > >> Why do you think it is a "trick"? Why do you think it is a "bit >> flimsy"? Why do you think it "isn't very elegant"? > > It requires that the key comparison function used in a map sorts the keys in > such a way that the last key/value pair includes the biggest key. If a map > is created with some other key comparison function then this trick fails. If your definition of 'biggest key' differs from the definition used by the key comparison function used by the map, then obviously you have to iterate over the map to find the 'biggest key' according to your definition.
[toc] | [prev] | [next] | [standalone]
| From | Paavo Helde <myfirstname@osa.pri.ee> |
|---|---|
| Date | 2012-02-11 16:39 -0600 |
| Message-ID | <Xns9FF76C46760Fmyfirstnameosapriee@216.196.109.131> |
| In reply to | #13922 |
Rui Maciel <rui.maciel@gmail.com> wrote in news:jh6ov5$7am$1@speranza.aioe.org: > Leigh Johnston wrote: > >> Why do you think it is a "trick"? Why do you think it is a "bit >> flimsy"? Why do you think it "isn't very elegant"? > > It requires that the key comparison function used in a map sorts the > keys in such a way that the last key/value pair includes the biggest > key. If a map is created with some other key comparison function then > this trick fails. No failing, rbegin() always (if the map is not empty) returns the last key - in the sorting order of the map, that is. This *is* the largest value, std::map does not know or care about any other sorting criterias you might want to use elsewhere in your code. hth Paavo
[toc] | [prev] | [next] | [standalone]
| From | Rui Maciel <rui.maciel@gmail.com> |
|---|---|
| Date | 2012-02-12 15:16 +0000 |
| Message-ID | <jh8l55$727$1@speranza.aioe.org> |
| In reply to | #13927 |
Paavo Helde wrote:
> No failing, rbegin() always (if the map is not empty) returns the last key
> - in the sorting order of the map, that is. This is the largest value,
> std::map does not know or care about any other sorting criterias you might
> want to use elsewhere in your code.
The std::map container is sorted, according to the key comparison function
used.
The rbegin() method returns an iterator pointing to the last element of the
range, but that range is sorted according to the key comparison function
used in a std::map.
So, as it is possible to pass any other key comparison function in a
std::map definition, rbegin() may or may not point to the element with the
biggest key.
To demonstrate:
<example>
rui@Kubuntu:tmp$ cat main.c++
#include <map>
#include <functional>
#include <iostream>
int main(void)
{
using namespace std;
map<int, int> lesser;
map<int, int, std::greater<int> > greater;
for(int i = 0; i < 10; i++)
{
lesser[i] = 2*i;
greater[i] = 2*i;
}
cout << "lesser:\n";
for(auto i: lesser)
{
cout << "\t(" << i.first << "," << i.second << ")";
}
cout << endl;
cout << "last element: " << "(" << lesser.rbegin()->first << "," <<
lesser.rbegin()->second << ")" << endl;
cout << "greater:\n";
for(auto i: greater)
{
cout << "\t(" << i.first << "," << i.second << ")";
}
cout << endl;
cout << "last element: " << "(" << greater.rbegin()->first << "," <<
greater.rbegin()->second << ")" << endl;
return 0;
}
rui@Kubuntu:tmp$ ./main
lesser:
(0,0) (1,2) (2,4) (3,6) (4,8) (5,10) (6,12) (7,14)
(8,16) (9,18)
last element: (9,18)
greater:
(9,18) (8,16) (7,14) (6,12) (5,10) (4,8) (3,6) (2,4)
(1,2) (0,0)
last element: (0,0)
</example>
Rui Maciel
[toc] | [prev] | [next] | [standalone]
| From | Goran <goran.pusic@gmail.com> |
|---|---|
| Date | 2012-02-12 08:41 -0800 |
| Message-ID | <ce87fec8-d707-4310-a6f2-b231428aa72f@hs8g2000vbb.googlegroups.com> |
| In reply to | #13939 |
On Feb 12, 4:16 pm, Rui Maciel <rui.mac...@gmail.com> wrote:
> Paavo Helde wrote:
> > No failing, rbegin() always (if the map is not empty) returns the last key
> > - in the sorting order of the map, that is. This is the largest value,
> > std::map does not know or care about any other sorting criterias you might
> > want to use elsewhere in your code.
>
> The std::map container is sorted, according to the key comparison function
> used.
>
> The rbegin() method returns an iterator pointing to the last element of the
> range, but that range is sorted according to the key comparison function
> used in a std::map.
>
> So, as it is possible to pass any other key comparison function in a
> std::map definition, rbegin() may or may not point to the element with the
> biggest key.
>
> To demonstrate:
>
> <example>
> rui@Kubuntu:tmp$ cat main.c++
> #include <map>
> #include <functional>
> #include <iostream>
>
> int main(void)
> {
> using namespace std;
> map<int, int> lesser;
> map<int, int, std::greater<int> > greater;
>
> for(int i = 0; i < 10; i++)
> {
> lesser[i] = 2*i;
> greater[i] = 2*i;
> }
>
> cout << "lesser:\n";
> for(auto i: lesser)
> {
> cout << "\t(" << i.first << "," << i.second << ")";
> }
> cout << endl;
> cout << "last element: " << "(" << lesser.rbegin()->first << "," <<
> lesser.rbegin()->second << ")" << endl;
>
> cout << "greater:\n";
> for(auto i: greater)
> {
> cout << "\t(" << i.first << "," << i.second << ")";
> }
> cout << endl;
> cout << "last element: " << "(" << greater.rbegin()->first << "," <<
> greater.rbegin()->second << ")" << endl;
>
> return 0;}
>
> rui@Kubuntu:tmp$ ./main
> lesser:
> (0,0) (1,2) (2,4) (3,6) (4,8) (5,10) (6,12) (7,14)
> (8,16) (9,18)
> last element: (9,18)
> greater:
> (9,18) (8,16) (7,14) (6,12) (5,10) (4,8) (3,6) (2,4)
> (1,2) (0,0)
> last element: (0,0)
> </example>
>
> Rui Maciel
map or set don't know anything about ordering your elements except the
comparison you give to them (or the default, std::less). map and set
are generic, and therefore don't know about numbers either.
I don't see why you expect them to know how elements should be
ordered, or that you might think they should be ordered.
Think about it this way: if your key wasn't a number or a string, how
do map or set even work? Something has to explain ordering to them.
And then, they both only know about __that__ particular ordering. They
aren't trying to guess that you are using std::greater and that there
is a "natural" "smaller" ordering they should ever use. For all they
know, you might pass in a comparison method where 42 is smaller than
anything else.
[toc] | [prev] | [next] | [standalone]
| From | Leigh Johnston <leigh@i42.co.uk> |
|---|---|
| Date | 2012-02-12 18:48 +0000 |
| Message-ID | <N_Odnbyl_coRlKXSnZ2dnUVZ8g2dnZ2d@giganews.com> |
| In reply to | #13939 |
On 12/02/2012 15:16, Rui Maciel wrote:
> Paavo Helde wrote:
>
>> No failing, rbegin() always (if the map is not empty) returns the last key
>> - in the sorting order of the map, that is. This is the largest value,
>> std::map does not know or care about any other sorting criterias you might
>> want to use elsewhere in your code.
>
> The std::map container is sorted, according to the key comparison function
> used.
>
> The rbegin() method returns an iterator pointing to the last element of the
> range, but that range is sorted according to the key comparison function
> used in a std::map.
>
> So, as it is possible to pass any other key comparison function in a
> std::map definition, rbegin() may or may not point to the element with the
> biggest key.
>
> To demonstrate:
>
> <example>
> rui@Kubuntu:tmp$ cat main.c++
> #include<map>
> #include<functional>
> #include<iostream>
>
>
> int main(void)
> {
> using namespace std;
> map<int, int> lesser;
> map<int, int, std::greater<int> > greater;
>
> for(int i = 0; i< 10; i++)
> {
> lesser[i] = 2*i;
> greater[i] = 2*i;
> }
>
> cout<< "lesser:\n";
> for(auto i: lesser)
> {
> cout<< "\t("<< i.first<< ","<< i.second<< ")";
> }
> cout<< endl;
> cout<< "last element: "<< "("<< lesser.rbegin()->first<< ","<<
> lesser.rbegin()->second<< ")"<< endl;
>
> cout<< "greater:\n";
> for(auto i: greater)
> {
> cout<< "\t("<< i.first<< ","<< i.second<< ")";
> }
> cout<< endl;
> cout<< "last element: "<< "("<< greater.rbegin()->first<< ","<<
> greater.rbegin()->second<< ")"<< endl;
>
> return 0;
> }
> rui@Kubuntu:tmp$ ./main
> lesser:
> (0,0) (1,2) (2,4) (3,6) (4,8) (5,10) (6,12) (7,14)
> (8,16) (9,18)
> last element: (9,18)
> greater:
> (9,18) (8,16) (7,14) (6,12) (5,10) (4,8) (3,6) (2,4)
> (1,2) (0,0)
> last element: (0,0)
> </example>
If you want to find the "biggest" element of *any* container you can use
'std::max_element' from <algorithm> and that applies here if by
"biggest" you don't mean the 'std::map' element that sorts greatest
according to the key comparison predicate. You should pass a custom
comparison predicate to 'std::max_element' as the 'value_type' of a
'std::map' is a pair (key and mapped type).
/Leigh
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.c++
csiph-web