如何找到地图中的最小值?
我有一个地图,我想找到地图中的最小值(右侧)。我是这样做的:
bool compare(std::pair<std::string ,int> i, pair<std::string, int> j) {
return i.second < j.second;
}
////////////////////////////////////////////////////
std::map<std::string, int> mymap;
mymap["key1"] = 50;
mymap["key2"] = 20;
mymap["key3"] = 100;
std::pair<char, int> min = *min_element(mymap.begin(), mymap.end(), compare);
std::cout << "min " << min.second<< " " << std::endl;
上面的代码运行良好,我能够获得最小值。但是,当我按如下方式将此代码放入我的类中时,它似乎不起作用:
int MyClass::getMin(std::map<std::string, int> mymap) {
std::pair<std::string, int> min = *min_element(mymap.begin(), mymap.end(),
(*this).compare);
// Error probably due to "this".
return min.second;
}
bool MyClass::compare(
std::pair<std::string, int> i, std::pair<std::string, int> j) {
return i.second < j.second;
}
如何使代码与我的类一起工作?另外,是否有更好的解决方案,不需要编写额外的 compare
函数?
I have a map
and I want to find the minimum value (right-hand side) in the map. Here is how I did it:
bool compare(std::pair<std::string ,int> i, pair<std::string, int> j) {
return i.second < j.second;
}
////////////////////////////////////////////////////
std::map<std::string, int> mymap;
mymap["key1"] = 50;
mymap["key2"] = 20;
mymap["key3"] = 100;
std::pair<char, int> min = *min_element(mymap.begin(), mymap.end(), compare);
std::cout << "min " << min.second<< " " << std::endl;
The code above works fine and I'm able to get the minimum value. However, when I put this code inside my class as follows, it doesn't seem to work:
int MyClass::getMin(std::map<std::string, int> mymap) {
std::pair<std::string, int> min = *min_element(mymap.begin(), mymap.end(),
(*this).compare);
// Error probably due to "this".
return min.second;
}
bool MyClass::compare(
std::pair<std::string, int> i, std::pair<std::string, int> j) {
return i.second < j.second;
}
How can I make the code work with my class? Also, is there a better solution which doesn't require writing the additional compare
function?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
在 C++11 中,您可以这样做:
或者将其放入像这样的漂亮函数中(注意我不是模板大师;这在很多方面可能是错误的):
使用 C++14,它进一步简化为:
In C++11 you can do this:
Or put it in a nice function like this (note I'm not a template guru; this is probably wrong in many ways):
With C++14, it further simplifies to:
你有几个选择。做到这一点的“最佳”方法是使用函子,这保证是最快的调用:(
您也可以将
CompareSecond
类嵌套在MyClass 中
。使用您现在的代码,您可以轻松修改它以使其工作,只需将函数设置为
静态
并使用正确的语法即可:You have a few options. The "best" way to do this is with a functor, this is guaranteed to be the fastest to call:
(You can also nest the
CompareSecond
class insideMyClass
.With the code you have now, you can easily modify it to work, however. Just make the function
static
and use the correct syntax:C++14
正如 Jonathan Geisler 的评论中提到的 蒂姆的回答,C++14 允许 lambda 函数 参数使用
auto
类型说明符进行声明。因此,您可以缩短 Timmmm 基于 lambda 的min_element
< /a> 行(并提高其可读性)如下:注 1:如果将此行放入
MyClass::getMin()
函数中,则必须返回it->second
。但是,为了考虑到空地图,您应该按如下所示(或类似)调整return
行:注 2:正如 Lance Diduck,您应该通过
const
传递地图引用您的getMin()
函数。按照您的方式,您正在创建整个地图的不必要的副本。Ideone 上的代码
C++14
As mentioned in Jonathan Geisler's comment on Timmmm's answer, C++14 allows lambda function parameters to be declared with the
auto
type specifier. As a result, you can shorten Timmmm's lambda-basedmin_element
line (and improve its readability) as follows:Note 1: If you put this line into your
MyClass::getMin()
function, you have to returnit->second
. However, to account for an empty map, you should adapt thereturn
line as follows (or similar):Note 2: As also mentioned by Lance Diduck, you should be passing the map by
const
reference to yourgetMin()
function. The way you did it, you are creating an unnecessary copy of the whole map.Code on Ideone
问题在于:
需要调用该类的实例。也就是说,您不能只调用
MyClass::compare
,而是需要someInstance.compare
。然而,min_element
需要前者。简单的解决方案是将其设为静态:
这不再需要调用实例,并且您的代码会很好。不过,您可以使用函子使其更加通用:
所有这一切都是从每对中抓取第二个并抓取它们,适用于任何对。可以说是通用的,但是有点太多了。
如果您需要按值进行足够的查找,我建议您使用Boost的 Bimap。它是一个双向映射,因此键和值都可以用于查找。您只需获取值键映射的前面即可。
最后,您始终可以跟踪进入地图的最小元素。每次插入新值时,检查它是否低于当前值(这可能应该是指向映射对的指针,以空值开头),如果低于当前值,则指向新的最低值。请求最低值变得像取消引用指针一样简单。
The problem is that this:
Requires an instance of the class to be called on. That is, you can't just call
MyClass::compare
, but you needsomeInstance.compare
. However,min_element
needs the former.The easy solution is to make it
static
:This no longer requires an instance to be called on, and your code will be fine. You can make it more general with a functor, though:
All this does is grab the second from each pair and grab them, works with any pair. It could be made for general, but that's a bit too much.
If you need to look up by value enough, I recommend you use Boost's Bimap. It's a bi-directional map, so both the key and value can be used to lookup. You would simply get the front of the value-key map.
Lastly, you can always just keep track of the minimum element going into your map. Every time you insert a new value, check if it's lower than your current value (and that should be probably be a pointer to a map pair, start it as null), and if it's lower, point to the new lowest. Requesting the lowest becomes as simple as dereferencing a pointer.
我实际上有另一个问题:如果您需要定期获取右侧值的最小值,您确定
map
是最好的结构吗?我建议一般使用 Boost.MultiIndex 来解决索引同一组对象的多种方法的问题......但如果您只需要这个“反向映射”位 Boost.Bimap 可能会更容易。
这样你在寻找最小值时就不会进行线性搜索:)
I actually have another question: if you need to regularly obtain the minimum of the right-hand side values are you sure than a
map
is the best structure ?I would suggest using
Boost.MultiIndex
in general for these problems of multiple ways of indexing the same set of objects... but if you only need this "reverse-mapping" bitBoost.Bimap
might prove easier.This way you won't have a linear search when looking for the minimum :)