#c #multimap
#c #multimap
Вопрос:
Я пытаюсь создать имя, а затем предоставить список курсов, которые прошел этот человек. Вот мой код на данный момент:
#include <iostream>
#include <string>
#include <map>
#include <list>
using namespace std;
int main()
{
multimap<string,string> students;
students.insert(make_pair("john","cs1"));
students.insert(make_pair("john","cs2"));
for (auto itr = students.begin(); itr != students.end(); itr)
{
cout << itr->first << 't' << itr->second << 'n';
}
}
При этом выводится:
John CS1
John CS2
Если бы я хотел заставить его распечатать первое значение, а затем распечатать все вторые значения, как бы я это сделал? Нужно ли мне использовать список в качестве второго значения или что-то в этом роде? Или это выполнимо только с несколькими картами? Например:
John CS1 CS2
Комментарии:
1. что вы имеете в виду под «распечатать все вторые значения»? распечатать все вторые значения, которые сначала = john?
2. Я хочу, чтобы он печатал первое значение карты, которое является John . после этого я хочу, чтобы в нем было указано каждое значение, связанное с john. Как у Джона CS1 CS2
Ответ №1:
Вы можете использовать equal_range
для достижения желаемого, см.:
std::string current_key = "";
for (auto itr = students.begin(); itr != students.end(); itr)
{
if(current_key == itr->first) {
continue;
} else {
current_key = itr->first;
}
const auto result = students.equal_range(itr->first);
cout << itr->first << ": ";
for(auto it = result.first; it != result.second; it) {
cout << it->second << " ";
}
cout << endl;
}
Смотрите рабочий пример здесь: https://ideone.com/RqCFOk
Комментарии:
1. довольно хорошее решение. причина, по которой это решается с помощью current_key, заключается в том, что multimap содержит отсортированный список пар ключ-значение.
2. Да, я не был уверен в этом, но это требование
std::multimap
, поэтому оно должно работать.3. Это именно то, что мне нужно! Большое вам спасибо. Не могли бы вы объяснить, для чего используется current_key, а также что equal_range делает для этого?
4. Всегда пожалуйста! Объяснение:
equal_range
возвращает все элементы для данного ключа — это почти именно то, что вам нужно. Но мы хотим использовать его для каждого ключа ровно один раз. Это цельcurrent_key
: при переборе всех ключей данный ключ будет встречаться хотя бы один раз, но мы хотим выполнить итерацию по данному ключу только один раз — следовательно, мы выполняем печать только для первого появления данного ключа. Если current_key == itr->first, это означает, что мы уже рассмотрели этот ключ, поэтому мы продолжаем и получаем следующий ключ.
Ответ №2:
В конечном итоге вы можете создать class
модель для моделирования учащегося, а пока вы можете просто выполнить итерацию по multimap
контейнеру и проверить, совпадает ли текущий ключ с предыдущим:
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <string>
using students_t = std::multimap<std::string, std::string>;
void print_students_list(students_t constamp; students)
{
// Start printing the name of the first student and the first course (the first key-value
// pair) if the container is not empty.
auto student{ students.cbegin() };
if ( student == students.cend() )
return;
std::cout << std::setw(12) << std::left << student->first
<< std::setw(8) << student->second;
// Then iterate over the rest of the container printing the name (after a newline)
// only if it's different from the previous one.
for ( auto prev{ student }; student != students.cend(); prev = student, student )
{
if ( student->first != prev->first )
std::cout << 'n' << std::setw(12) << student->first;
std::cout << std::setw(8) << student->second;
}
std::cout << 'n';
}
int main()
{
students_t students {
{"john", "cs1"},
{"john", "cs2"},
{"Karen", "cs2"},
{"Karen", "nc1"},
{"Karen", "nc2"},
{"Bob", "nc1"}
};
print_students_list(students);
}