C++ 在map中查找值最多的键<;字符串,向量<;字符串>&燃气轮机; set myFunc(常量映射&m)

C++ 在map中查找值最多的键<;字符串,向量<;字符串>&燃气轮机; set myFunc(常量映射&m),c++,stl,stdmap,stdset,C++,Stl,Stdmap,Stdset,我想返回一组字符串中的所有键,这些字符串映射了最多的值(如果映射值的数量相同,则有几个键)。我的尝试是: set<string> myFunc (const map<string, vector<string>>& m) set-ret; auto max_e=*max_元素(m.begin(),m.end(),[](常数对和m1,常数对和m2){ 返回m1.second.size()second; values.size()==maximumSiz

我想返回一组字符串中的所有键,这些字符串映射了最多的值(如果映射值的数量相同,则有几个键)。我的尝试是:

set<string> myFunc (const map<string, vector<string>>& m)
set-ret;
auto max_e=*max_元素(m.begin(),m.end(),[](常数对和m1,常数对和m2){
返回m1.second.size()

从逻辑上讲,这是行不通的(我认为),因为这只会返回一个具有最高值的键。有什么想法吗?

一种方法是迭代两次:

  • 第一个可以从所有钥匙中获得最大尺寸的钥匙
  • 第二个是获取映射到该大小的键
它应该遵循以下几点:

set<string> ret;
auto max_e = *max_element(m.begin(), m.end(), [] (const pair<string, vector<string>>& m1, const pair<string, vector<string>>& m2) {
    return m1.second.size() < m2.second.size();
  });
ret.insert(max_e.first);
return ret;
set myFunc(常量映射&m){
设置ret;
大小\u t最大大小=0;
用于(施工自动和电气:m){
maximumSize=max(maximumSize,e.second.size());
}
用于(施工自动和电气:m){
如果(例如秒大小()==最大大小){
重新插入(e.首先);
}
}
返回ret;
}

除了@a.Li的答案,如果可能的话,您还可以在此过程中优化很多东西

当然,迭代地图两次可能是解决问题的最省钱、最简单的方法:

set <string> myFunc(const map<string, vector<string>>& m) {
    set <string> ret;
    size_t maximumSize = 0;
    for (const auto& e : m) {
        maximumSize = max(maximumSize, e.second.size());
    }
    for (const auto& e : m) {
        if (e.second.size() == maximumSize) {
            ret.insert(e.first);
        }
    }
    return ret;
}
使用StringMapType=std::map;
使用StringMapVectorType=StringMapType::value\u type::second\u type;
标准::设置findKeys(常量StringMapType和stringMap){
StringMapVectorType::size_type maximumSize{};
对于(常量自动和[key,values]:stringMap)
maximumSize=std::max(maximumSize,values.size());
std::设置结果{};
对于(常量自动和[key,values]:stringMap)
if(values.size()==maximumSize)
结果:安置(关键);
返回结果;
}
不过,如果可能的话,我会提出以下建议:

  • 如果您对在地图类型中排序键不感兴趣,请使用
  • 如果您对结果中存储的键的顺序不感兴趣,请将返回值类型(替换为)
特定于对象生存期的优化:

  • 用于找到的键;这将避免字符串的额外副本,假设它们没有使用
  • 返回迭代器数组,而不是它们的键
如果应用,代码可能如下所示:

using StringMapType = std::map<std::string, std::vector<std::string>>;
using StringMapVectorType = StringMapType::value_type::second_type;

std::set<StringMapType::key_type> findKeys(const StringMapType &stringMap) {
    StringMapVectorType::size_type maximumSize {};
    for (const auto &[key, values] : stringMap)
        maximumSize = std::max(maximumSize, values.size());
    
    std::set<StringMapType::key_type> results {};
    for (const auto &[key, values] : stringMap)
        if (values.size() == maximumSize)
            results.emplace(key);
    
    return results;
}
std::vector findKeys(常量StringMapType和stringMap){
StringMapVectorType::size_type maximumSize{};
对于(常量自动和[key,values]:stringMap)
maximumSize=std::max(maximumSize,values.size());
std::向量结果{};
对于(自动迭代器=stringMap.cbegin();迭代器!=
stringMap.cend();++迭代器)
if(const auto&values=iterator->second;
values.size()==maximumSize)
结果:向后放置(迭代器);
返回结果;
}
当然,如果您想避免整个问题,可以在插入时使用自定义比较器对值进行排序,或者找到数组中元素最多的条目,然后在其前面插入新条目(当然,您必须使用无序映射或其他容器)

对未来有用的东西:


找到最大元素的大小,而不是最大元素本身的大小,然后您可以添加具有该大小的所有元素。您只需进行一次迭代即可-每当您找到键更大的元素时,请重置结果集,添加当前值,然后继续。@BitTicker True,尽管我认为多次重置结果集将是一个错误虽然
set.clear()
有点贵。但我不确定OP是否关心性能。我只用了一次迭代就解决了这个问题,谢谢大家!
    std::vector<StringMapType::const_iterator> findKeys(const StringMapType &stringMap) {
        StringMapVectorType::size_type maximumSize {};
        for (const auto &[key, values] : stringMap)
            maximumSize = std::max(maximumSize, values.size());
        
        std::vector<StringMapType::const_iterator> results {};
        for (auto iterator = stringMap.cbegin(); iterator != 
             stringMap.cend(); ++iterator)
            if (const auto &values = iterator->second;
                values.size() == maximumSize)
                results.emplace_back(iterator);
        
        return results;
    }