Печать на C с несколькими картами

#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);  
}