C ++ с использованием std :: find на карте, где ключ является пользовательским классом - PullRequest
0 голосов
/ 21 ноября 2018

Я новичок в C ++, и я боролся с этим последние пару дней.У меня есть задача, где мне нужно создать карту (неупорядоченная или многопользовательская не допускается).1. Ключом для карты должен быть класс SportTeam и в нем должна быть строковая страна и строковая спортивная дисциплина.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.

Я попытался следоватьСправочник по cpp для std :: find, который предлагает что-то вроде этого:

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класс с 2 участниками (страна и спортивная дисциплина).Я должен использовать функцию map :: find, чтобы проверить, если страна = "Польша", и я не могу заставить ее работать.

Ответы [ 2 ]

0 голосов
/ 22 ноября 2018

Вам нужно std :: find_if или std :: any_of , где вы можете иметь UnaryPredicate (или лямбда-функцию), чтобы дать логику сравнения.

В Интернете доступно множество примеров использования этих алгоритмов.

0 голосов
/ 21 ноября 2018
mapOfTeams.find(SportTeam("Poland", "Volleyball"));

работает.

https://godbolt.org/z/K0Akq6

Вам необходимо создать объект типа ключа, чтобы сравнить ключи.Вы не можете создать объект SportTeam, основываясь только на названии страны, так как вам требуются как название страны, так и дисциплина.

Чтобы эффективно использовать карту / хэш / словарь / ассоциативный массив, необходимо сделатьОбязательно набирайте их по тому, что вы хотите найти.Если вы хотите найти что-то другое (только для страны), то вам нужно будет перебрать все записи, ищущие страну - что менее эффективно.

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

Или, как другие предложили,вы можете сделать find_if с пользовательским компаратором, но это по сути тот же код, что и выше, и при этом не использовать эффективность поиска в map.

...