问题描述
set<string> myFunc (const map<string,vector<string>>& m)
我想返回一组字符串中的所有键,这些键映射了最多的值(如果映射值的数量相同,则为几个键)。我的尝试是:
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 <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;
}
,
除了@a.Li的回答,如果可能的话,你也可以一路优化不少东西。
当然,对地图进行两次迭代可能是解决问题的成本最低且最简单的方法:
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::unordered_map,
- 替换返回值类型(std::set 为 std::vector,如果您对结果中存储的键的顺序不感兴趣。
对象生命周期特定的优化:
- 使用 std::string_view 作为您找到的键;这将避免额外的字符串副本,假设它们没有用 short string optimization,
- 返回一个迭代器数组,而不是它们的键
如果应用,代码可能如下所示:
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;
}
当然,如果您想避免整个问题,您可以在插入时使用自定义比较器对您的值进行排序,或者找到其数组中元素数量最多的条目,然后插入之前的新条目(当然,您必须使用无序映射或其他容器)。
对未来有用的东西: