#c #hashmap
#c #hashmap
Вопрос:
Привет, мой наставник (вроде как) дал мне эту задачу, и у меня возникли проблемы с ее решением.
Итак, в основном я const vector<string> amp;data
заполняюсь строками, и мне нужно проверить их место, например, где они находятся в этом векторе, так что вот пример:
получение входных данных с: data={"chair","desk","table","chair","chair","desk"}
мой вывод должен быть: {"chair" ->{0,3,4},"desk"->{1,5} , "table"->{2}}
итак, что я сделал :
map<string, set<size_t>> index(const vector<string> amp; data) noexcept {
map<string, set<size_t>> res; // thats gon be my return
if (data.empty()){
return res;
}
for (auto it = data.begin(); it != data.end(); it ) {
if(res.find(*it)==res.end()){
//so basically when we are the first , and nothing is there so
// it should insert for example =chair , and a 0
res.insert(std::make_pair(*it, 0)); // i tried it like that it doesnt work
}else{
// when the string "chair is already in there i want to append to the set the current index where we are and thats what i dont know how
}
}
return res;
}
как получить индекс текущей строки и добавить его к моему набору <size_t>, чтобы это работало, как упоминалось?
Комментарии:
1. Вы забыли сказать, что не так с вашим кодом.
2. я прошу совета, в моем коде нет ничего плохого, нужна помощь в том, как реализовать эту задачу в моем коде, как получить индекс текущей строки и добавить его в мой set<size_t>
3. какой индекс? Позиция в векторе?
4. да, это то, что я имел в виду
Ответ №1:
Вы можете реализовать это довольно легко, используя цикл на основе индекса:
map<string, set<size_t>> index(const vector<string> amp; data)
{
map<string, set<size_t>> res;
for (std::size_t i = 0u; i < data.size(); i)
res[ data[i] ].insert(i);
// ^string^ ^index
return res;
}
Комментарии:
1.
decltype(data.size())
? почему это?2. @MICHAEL Good, я рад 🙂 Не забудьте принять ответы, которые решают вашу проблему, когда вам разрешено это принять.
3. @largest_prime_is_463035818 Просто чтобы быть полностью уверенным, что типы совпадают. Как правило, это не проблема, но вреда в этом нет. Также приятно четко указать, какой именно тип требуется.
4. @largest_prime_is_463035818 Конечно, правильным способом было бы использовать библиотеку диапазонов или написать какой-нибудь код, который позволяет писать
for (auto [i, elem] : data)
и не возиться с типами индексов 🙂5. Нет, мы знаем, что
vector::size
в основном всегда возвращается; просто имейтеfor (std::size_t i = 0; i < data.size(); i)
и перестаньте сбивать всех с толку без необходимости!
Ответ №2:
#include <iostream>
#include <string>
#include <vector>
#include <set>
#include <map>
std::map<std::string, std::set<size_t>> index(const std::vector<std::string>amp; data) noexcept
{
std::map<std::string, std::set<size_t>> res;
for (size_t idx = 0u; idx < data.size(); idx )
{
res[data[idx]].insert(idx);
}
return res;
}
int main()
{
const std::vector<std::string> data={"chair","desk","table","chair","chair","desk"};
auto map = index(data);
for( auto it = map.begin(); it != map.end(); it )
{
std::cout << (*it).first << " ->";
for( auto it_id = (*it).second.begin(); it_id != (*it).second.end(); it_id )
{
std::cout << " " << *it_id;
}
std::cout << "n";
}
}
Таким образом, ваша проблема может быть решена с помощью oneline , как показано в функции index , но почему?
Существует причина, по которой вы получаете все эти разные типы контейнеров std в качестве входных данных — у каждого из них есть некоторые гарантии, которые можно посмотреть в документации.
векторные элементы являются непрерывными в памяти (контейнер последовательности).
в то время как map и set являются ассоциативными и имеют уникальные ключи.
Обратитесь к документации для свойств контейнера (я ссылался на вектор, но остальные также присутствуют в дереве слева). http://www.cplusplus.com/reference/vector/vector /
Урок заключается в том, чтобы знать, какой инструмент (контейнер) использовать для решения конкретных задач
И как только вы это поймете … убедиться, что элементы уникальны или как упорядочить каждый нечетный элемент в векторе, должно быть проще простого.