【问题标题】:C++ using std::find in a map where the key is a custom classC++ 在键是自定义类的地图中使用 std::find
【发布时间】:2018-11-20 22:47:07
【问题描述】:

我是 C++ 新手,过去几天我一直在为此苦苦挣扎。 我有一项任务需要创建地图(不允许无序或多表)。 1. 地图的键必须是一个类 SportTeam,它应该有一个字符串国家和一个字符串 sportsDiscipline。 2. 每个键的值是一个字符串向量。 3. 创建地图后,我应该使用 STL 查找功能检查是否有任何键将波兰作为国家/地区。

这是我创建地图的方式:

SportTeam team1{"USA", "Hockey"}, 
team2{"Poland", "Volleyball"}, 
team3{"France", "Running"},
team4{"China", "Swimming"}, 
team5{"Poland","Tennis"};
using  mapVector = std::vector<std::string>;
std::map<SportTeam,mapVector> mapOfTeams;
mapOfTeams[team1].emplace_back("Team Beavers");
mapOfTeams[team2].emplace_back("Team Badgers");
mapOfTeams[team3].emplace_back("Team Snails");
mapOfTeams[team4].emplace_back("Team Doggos");
mapOfTeams[team5].emplace_back("Team Pinguins");

这是我的头文件:

class SportTeam {
public:
std::string country;
std::string sportsDiscipline;

SportTeam(std::string newCountry, std::string 
newDiscipline) :
country{std::move(newCountry)},
sportsDiscipline{std::move(newDiscipline)}
{};

bool operator <(const SportTeam& other)const{
    return country < other.country || (country == 
other.country && sportsDiscipline < 
other.sportsDiscipline);
}
};

问题是我不知道如何使用查找功能检查班级成员。像这样访问迭代器时,我能够找到国家/地区

mapIt->first.country

然后在迭代器循环中的 if 语句中比较它,但是我不能用 find 函数复制它。

我尝试遵循 std::find 的 cpp 参考指南,该指南建议如下:

auto search = example.find(2);
if (search != example.end()){
...}

但如果我在地图本身上尝试它就不起作用,因为它不识别“波兰”。我尝试了不同的语法组合,但我能够访问国家成员的唯一方法是当我尝试这个时:

auto mapIt = mapOfTeams.begin();
auto search = 
mapIt->first.country.find("Poland");

此选项不允许我将结果与 mapOfTeam.end() 进行比较,因为 cpp 参考建议,因为它会引发错误!= 说它是无效的操作数。

任何帮助将不胜感激。我在堆栈和其他论坛上花了很长时间,但我无法找到解决问题的方法,因此我决定鼓起勇气在这里写我的第一篇文章:)

TL;DR Key 是一个有 2 个成员(国家和体育学科)的类。我必须使用 map::find 函数来检查 country = "Poland" 是否无法正常工作。

【问题讨论】:

  • example.find(SportTeam("Poland")); - c++ 将搜索多少个类型构造规则的规则有点奇怪。
  • 您可能正在寻找std::find_if
  • @xaxxon 我之前试过这个 mapOfTeams.find(SportTeam("Poland")) 但我得到一个错误“从 const char[7] 到 SportTeam 的函数式转换之间没有匹配的转换
  • @yedolte 你忘了SportTeam 构造函数的第二个参数
  • 在 lamda 中使用 find_if map 方法。

标签: c++ c++14 c++17


【解决方案1】:
mapOfTeams.find(SportTeam("Poland", "Volleyball"));

有效。

https://godbolt.org/z/K0Akq6

您必须创建一个键类型的对象才能比较键。您不能仅基于国家名称构建 SportTeam 对象,因为您需要国家名称和学科。

为了有效地使用 map/hash/dictionary/associative-array,您需要确保通过您要查找它们的东西来键入它们。如果您想通过其他方式(仅限国家/地区)进行查找,则需要遍历所有搜索该国家/地区的条目 - 效率较低。

for(auto const & sports_team : mapOfTeams) {
  if (sports_team.first.country == "Poland") {
    // do whatever with match
  }
}

或者正如其他人所建议的那样,您可以使用自定义比较器执行 find_if,但这与我在上面放置的代码基本相同 - 并且仍然没有利用 map 中查找的效率。

【讨论】:

  • 有点挑剔,这不是问题所要求的。它没有说明必须指定或知道sportsDicipline。但是,如果这是一个选项,这确实可以正常工作。
  • @super 寻址。
  • 感谢您的回答。不幸的是,它只能按国家/地区进行。我有两个对象的国家为波兰,但它们的学科不同。解决方案应该返回两个对象。任务是使用 find 函数,但正如一些帖子所暗示的那样,我可能将它与 find_if 混淆了
  • 您知道,由于 C++14 的 std::map 可以有一个透明的比较器,因此无需创建用于比较的键。
【解决方案2】:

您需要std::find_ifstd::any_of,您可以在其中使用UnaryPredicate(或lambda 函数)来提供比较逻辑。

互联网上有大量关于如何使用此算法的示例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-15
    • 1970-01-01
    • 1970-01-01
    • 2011-10-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多