Как вывести map c
Перейти к содержимому

Как вывести map c

  • автор:

Developing.ru

Пишу архиватор. С контейнирами только знакомлюсь. Всё получалось до тех пор пока не пришлось вывести map в котором находится символ типа char, и vector. По алгоритму Хаффмана моя программа строит дерево, каждому символу присваивает соответствующий код в зависимости от частоты появления этого символа. Вот собственно сам код:

#include #include #include #include #include using namespace std; class Node < public: int a; char c; Node *left, *right; Node ()<>; Node (Node *L, Node *R) < left = L; right = R; a=L->a+R->a; > >; struct MyCompare < bool operator()(Node* l, Node* r) const < return l->a < r->a; > >; vector code; map  table; map ::iterator itrCode; void BuildTable (Node *root) < if (root->left!=NULL) < code.push_back(0); BuildTable (root->left); > if (root->right!=NULL) < code.push_back(1); BuildTable (root->right); > if (root->c) < table[root->c]=code; > code.pop_back(); > void print (Node* root, unsigned k=0) < if (root!=NULL) < print (root->left, k+3); for (unsigned i=0; i if (root->c) cout a << " (" c << ") " << endl; else cout a right, k+3); > > int main() < string s="Waiting for the san"; map m; for (int i=0; i map ::iterator itr; list t; for (itr=m.begin(); itr!=m.end(); itr++) < //cout first << ":" second c=itr->first; p->a=itr->second; t.push_back(p); > while (t.size()!=1) < t.sort (MyCompare()); Node *SonL=t.front(); t.pop_front(); Node *SonR=t.front(); t.pop_front(); Node *parent = new Node(SonL, SonR); t.push_back(parent); >Node *root=t.front(); //unsigned k=0; //print (root, k); BuildTable (root); for (itrCode=table.begin(); itrCode!=table.end(); itrCode++) < cout first second; > >

Вот этот вывод который я пытался написать:

for (itrCode=table.begin(); itrCode!=table.end(); itrCode++) < cout first second; > 

Но ему это не нравится. Если просто писать

cout first;

то всё хорошо, как только пытаюсь второй элемент (вектор) вывести, тут он не хочет. Подскажите что не так я делаю. Уже всю голову сломал.

Romeo Сообщения: 3091 Зарегистрирован: 02 мар 2004, 17:25 Откуда: Крым, Севастополь Контактная информация:

У тебя second в мапе является вектором, а не build-in значением. Так что у stream’а нету соответствующего оператора <<, чтобы вывести его.

Выводить придётся руками:

for (itrCode=table.begin(); itrCode!=table.end(); itrCode++) < cout first & vec = itrCode->second; for (vector::iterator it = vec.begin(); it != vec.end(); ++it) < cout cout

Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.

Как вывести map c

Карта или std::map представляет контейнер, где каждое значение ассоциировано с определенным ключом. И по этому ключу можно получить элемент. Причем ключи могут иметь только уникальные значения. Примером такого контейнера может служить словарь, где каждому слову сопоставляется его перевод или объяснение. Поэтому такие структуры еще называют словарями.

Стандартная библиотека C++ предоставляет два типа словарей: std::map и std::unordered_map . Эти типы представляют шаблоны, которые типизируются двумя типами. Первый тип - Key задает тип для ключей, а второй тип - Value устанавливает тип для значений.

Тип std::map определен в заголовочном файле . Определение пустого словаря:

#include #include int main() < std::mapproducts; >

Здесь определен словарь products, который будет условно хранить цену товаров. Для ключей будет применяться тип std::string , а для значений - числа типа unsigned (условно в качестве ключа будет выступать название товара, а в качестве значения - его цена).

Обращение к элементам

Для обращения к элементам словаря - получения или изменения их значений, так же, как в массиве или векторе, применяется оператора индексирования [] . Только вместо целочисленных индексов можно использовать ключи любого типа в следующем виде:

map[ключ]=значение

#include #include int main() < std::mapproducts; // установка значений products["bread"] = 30; products["milk"] = 80; products["apple"] = 60; // получение значений std::cout

Здесь определен словарь products, в котором ключами служат строки, а значениями - числа типа unsigned. Поэтому для установки элемента в квадратные скобки передается ключ-строка, а присваивается значение-число:

products["bread"] = 30;

Будем считать, что ключ - название товара, а значение - цена товара. То есть в данном случае элементу с ключом "bread" присваивается значение 30. При этом не важно, что ранее создан пустой словарь, и в нем нет никакого элемента с ключом "bread" - если его нет, то он создается. Если же элемент с данным ключом уже есть, то меняется его значение.

Чтобы получить элемент по определенному ключу, используем тот же синтаксис. Например, поскольку значение элемента - число, то мы можем, обратившись по ключу, получить это число:

unsigned breadPrice = products["bread"];

В выше приведенной программе просто выводим значения элементов на консоль:

bread 30 milk 80 apple 60

Перебор элементов:

Для перебора элементов можно применять цикл for в стиле "for-each":

#include #include int main() < std::mapproducts; // установка значений products["bread"] = 30; products["milk"] = 80; products["apple"] = 60; for (const auto& [product, price] : products) std::cout

Рассмотрим определение цикла. Каждый элемент словаря фактически представляет объект типа std::pair , который хранит, как ключ, так и значение. В нашем случае это объект std::pair . И с помощью полей first и second данного объекта мы могли бы получить соответственно ключ и значение элемента:

for (const auto& element : products) std::cout 

Но начиная со стандарта С++17 также можно использовать другой синтаксис, который позволяет сразу разложить объект на отдельные части - ключ и значение:

for (const auto& [product, price] : products) std::cout 

В данном случае в product будет помещаться ключ, а в price - значение элемента словаря. В итоге при выполнении программы мы получим следующий консольный вывод:

apple 60 bread 30 milk 80

Обратите внимание, что элементы располагаются в словаре и соответственно выводятся на консоль по возрастанию ключей. Поскольку ключи представляют строки, то они сортируются в алфавитном порядке.

Инициализация элементов

Тот факт, что в словаре элементы представляют тип std::pair, позволяет инициализировать словарь объектами std::pair:

#include #include int main() < std::mapproducts < std::pair, std::pair, std::pair >; >

И даже можно сократить определение:

#include #include int main() < std::mapproducts < , , >; >

Удаление элементов

Как было показано выше, для добавления элемента в словарь достаточно просто установить для некоторого ключа какой-нибудь значение. Для удаления же элементов применяется функция erase() , в которую передается ключ удаляемого элемента:

#include #include int main() < std::mapproducts < , , >; products.erase("milk"); // удаляем элемент с ключом "milk" for (const auto& [product, price] : products) std::cout 

Размер словаря

Для получения количества элементов в словаре применяется функция size() . Также класс map имеет функцию empty() , которая возвращает true , если словарь пуст.

#include #include int main() < std::mapproducts < , , >; std::cout 

Проверка наличия элемента

Чтобы проверить, есть ли в словаре элемент с определенным ключом, применяются функции count() (возвращает 1, если элемент есть, и 0 - если отсутствует) и contains() (возвращает true, если элемент есть, и false - если отсутствует). В обе функции передается ключ элемента:

#include #include int main() < std::mapproducts < std::pair, std::pair, std::pair >; std::cout 

Неупорядоченные словари

Тип std::map определяет словарь, который упорядочиваниет все свои элементы - по умолчанию в порядке возрастания ключей. Если упорядоченность не нужна, можно применять ти std::unordered_map , который в целом предоставляет тот же самый функционал, только не упорядочивает элементы и определен в заголовочном файле

#include #include int main() < std::unordered_mapproducts < std::pair, std::pair, std::pair >; for (const auto& [product, price] : products) std::cout

apple 60 milk 80 bread 30

Итераторы

Стоит отметить, что итераторы типа std::map являеются константными, что не позволяет изменять значения элементов при переборе:

#include #include int main() < std::mapphoneBook < , , >; for(auto iter; iter != phoneBook.end(); iter++) < std::cout first << "\t" second // для получения итераторов также можно использовать функции cbegin и cend for(auto iter; iter != phoneBook.cend(); iter++) < std::cout first << "\t" second >

Как вывести на экран все значения элементов лежащих по одному ключу в std::map?

Как вывести на экран все значения элементов лежащих по одному ключу в std::map? вот у меня есть контейнер std::map, в нем содержится:
merlok 89-09-23
merlok 66-66-66
merlok 12-34-56
задача вывести все номера по ключу surname, где surname это merlok

#include #include #include struct data < std::string number; std::string surname; >user; void add(std::map& surname_book, std::map& phone_book) < while (1) < std::cout > user.number; if (user.number == "0") < system("cls"); break; >std::cout > user.surname; phone_book.insert( std::pair(user.number, user.surname)); surname_book.insert( std::pair(user.number, user.surname)); > > void search_by_surname(std::map& surname_book) < std::string surname; std::cout > surname; std::map::iterator it = surname_book.begin(); if (it == surname_book.end()) < std::cout else < std::cout first > > void search_by_number(std::map& phone_book) < std::string number; std::cout > number; std::map::iterator it = phone_book.find(number); std::cout << "Founds:\n"; if (it == phone_book.end()) < std::cout else < std::cout first << " " second > int main() < std::mapsurnameBook; std::map phoneBook; while (1) < std::cout > choice; if (choice == "0") < system("cls"); break; >if (choice == "add") < add(surnameBook, phoneBook); >else if (choice == "find") < std::cout > ans; switch (ans) < case 1: search_by_number(phoneBook); break; case 2: search_by_surname(surnameBook); break; >system("pause"); system("cls"); > > std::cout
  • Вопрос задан более двух лет назад
  • 417 просмотров

1 комментарий

Простой 1 комментарий

loganbaby

logan baby @loganbaby Автор вопроса
и сделать это за O(logN).
Решения вопроса 0
Ответы на вопрос 2

Rsa97

Для правильного вопроса надо знать половину ответа

ЕМНИП, у std:map не может быть нескольких элементов с одним ключом. Так что просто
surname_book.find(surname)

Ответ написан более двух лет назад

loganbaby

logan baby @loganbaby Автор вопроса

я неверно поставил вопрос. взгляните на код, при вводе add надо ввести "номер телефона" и "фамилию". что то типо телефонной книги. я могу ввести также одинаковые фамилии на разные номера телефонов, но не одинаковые номера телефонов на разные фамилии. как их вывести за logN? с циклом (как у меня) получается за O(N), в этом и заключалась суть вопроса)))

#include #include #include struct data < std::string number; std::string surname; >user; void add(std::map& surname_book, std::map& phone_book) < while (1) < std::cout > user.number; if (user.number == "0") < system("cls"); break; >std::cout > user.surname; phone_book.insert( std::pair(user.number, user.surname)); surname_book.insert( std::pair(user.number, user.surname)); > > void search_by_surname(std::map& surname_book) < std::string surname; std::cout > surname; std::map::iterator it = surname_book.begin(); if (it == surname_book.end()) < std::cout else < std::cout first > > void search_by_number(std::map& phone_book) < std::string number; std::cout > number; std::map::iterator it = phone_book.find(number); std::cout << "Founds:\n"; if (it == phone_book.end()) < std::cout else < std::cout first << " " second > int main() < std::mapsurnameBook; std::map phoneBook; while (1) < std::cout > choice; if (choice == "0") < system("cls"); break; >if (choice == "add") < add(surnameBook, phoneBook); >else if (choice == "find") < std::cout > ans; switch (ans) < case 1: search_by_number(phoneBook); break; case 2: search_by_surname(surnameBook); break; >system("pause"); system("cls"); > > std::cout

Методы, обеспечивающие получение информации из контейнера

Методы begin() и end() позволяют получить итератор на начало и конец ассоциативного массива. Конец ассоциативного массива определяется как элемент, следующий за последним элементом массива.
Общая форма объявления методов следующая:

iterator begin(); const iterator begin() const; iterator end(); const iterator end() const;

На рисунке 1 показан пример, в котором показаны позиции, возвращаемые методами begin() и end() .

C++. Класс map. Методы begin(), end(). Начало и конец ассоциативного контейнера

Рисунок 1. Возврат результата методами begin() и end()

Пример.

В примере формируется ассоциативный контейнер, изображенный на рисунке 1. Затем с помощью методов begin() и end() определяются границы контейнера и происходит вывод контейнера на экран с помощью итератора.

#include iostream> #include map> using namespace std; void main() < // Методы begin() и end() // 1. Создать ассоциативный контейнер mapint, string> m1; m1.insert(pairint, string>(1, "Winter")); m1.insert(pairint, string>(2, "Spring")); m1.insert(pairint, string>(3, "Summer")); m1.insert(pairint, string>(4, "Autumn")); // 2. Получить итератор на начало и конец контейнера mapint, string>::iterator it, itEnd; it = m1.begin(); itEnd = m1.end(); // 3. Вывести содержимое контейнера на экран cout "m1:" while (it!=itEnd) < cout first " : " second >
m1: 1 : Winter 2 : Spring 3 : Summer 4 : Autumn
3. Метод count() . Получить количество дубликатов по ключу

Метод count() возвращает количество дубликатов элемента со значением ключа. Данный метод актуален для класса multimap , в котором одному ключу может соответствовать несколько значений. Общая форма объявления метода следующая:

inline size_t count(const keyType &keyVal) const;
  • keyType – тип ключа;
  • keyVal – значение ключа.

Пример.

#include iostream> #include map> using namespace std; void main() < // Метод count() - получить количество дубликатов по заданному ключу // 1. Сформировать ассоциативный массив mapchar, string> Colors; Colors.insert(make_pair('R', "Red")); Colors.insert(make_pair('G', "Green")); Colors.insert(make_pair('B', "Blue")); // 2. Попытка создать еще один дубликат ключа 'B' Colors.insert(make_pair('B', "Black")); // работает // 3. Вывести количество дубликатов для ключа 'B' cout 'B') // 1 // 4. Вывести количество дубликатов для ключа 'R' cout 'R') // 1 // 5. Попытка доступиться к несуществующему ключу try < cout 'F') // 0 > catch (out_of_range e) < cout >
1 1 0
4. Метод empty() . Определить, пуст ли массив

Метод empty() позволяет определить, есть ли в ассоциативном контейнере элементы. Спецификация метода имеет вид

inline bool empty() const;

Метод возвращает true , если в контейнере имеется хотя бы один элемент. Иначе метод возвращает false .

Пример.

#include iostream> #include map> using namespace std; void main() < // Метод empty() - определить, пуст ли массив // 1. Создать пустой контейнер mapint, char> m1; // 2. Вызвать функцию empty() if (m1.empty()) cout "m1 is empty" else cout "m1 is not empty" // 3. Прибавить к контейнеру несколько элементов m1.insert(make_pair(1, 'A')); m1.insert(make_pair(2, 'B')); m1.insert(make_pair(3, 'C')); // 4. Повторно вызвать empty() if (m1.empty()) cout "m1 is empty" else cout "m1 is not empty"

m1 is empty m1 is not empty
5. Метод find() . Получить итератор на заданный ключ

Метод find() возвращает итератор, установленный на заданный ключ. Синтаксис объявления наиболее распространенных реализаций метода имеет вид:

inline iterator find(const keyType &keyVal) const; inline iterator find(const keyType &keyVal);
  • keyType – тип ключа;
  • keyVal – значение ключа.

Пример.

#include iostream> #include map> using namespace std; void main() < // Метод find() - найти элемент по ключу // 1. Сформировать ассоциативный массив mapbool, string> m1; m1.insert(make_pair(true, "True")); m1.insert(make_pair(false, "False")); // 2. Найти ключ true и вывести его mapbool, string>::iterator it; it = m1.find(true); cout first " : " second // 3. Найти ключ false и вывести его it = m1.find(false); cout first " : " second

1 : True 0 : False
6. Метод max_size() . Максимальный размер контейнера

Метод max_size() возвращает максимальное количество элементов в контейнере. Это количество зависит от типа ключа и значения в паре, размера свободной памяти и т.д.

Синтаксис объявления метода

inline size_t max_size() const;

Пример.

#include iostream> #include map> using namespace std; void main() < // Метод max_size() - получить максимально возможный размер контейнера // 1. Объявить пустой контейнер mapstring, string> code; // 2. Прибавить к контейнеру элемент code.insert(make_pair("USA", "1")); // 3. Вывести max_size() cout // 164703072086692425 // 4. Прибавить еще элемент code.insert(make_pair("Ukraine", "380")); // 5. Вывести max_size() cout // 164703072086692425 >
164703072086692425 164703072086692425
7. Метод size() . Получить текущее количество элементов в массиве

Метод size() возвращает количество элементов в ассоциативном контейнере. При создании пустого контейнера метод вернет 0.

Синтаксис объявления метода

inline size_t size() const;

Пример.

#include iostream> #include map> using namespace std; void main() < // Метод size() - получить размер контейнера // 1. Объявить пустой контейнер mapstring, string> code; // 2. Получить размер контейнера int size = code.size(); cout // 0 // 3. Прибавить к контейнеру элемент code.insert(make_pair("USA", "1")); // 4. Вывести size() cout // 1 // 5. Прибавить еще элемент code.insert(make_pair("Ukraine", "380")); // 6. Вывести size() cout // 2 >
0 1 2
8. Операторная функция operator[]() . Получить значение по заданному ключу

С помощью операторной функции operator[]() можно обращаться к значениям массива по его ключам естественным способом с помощью квадратных скобок [] . Синтаксис объявления функции в классе map следующий

inline vType& mapkType, vType>::operator[](kType &&_KeyVal);
  • kType – тип ключа;
  • vType – тип значения;
  • _KeyVal – значение ключа.

Метод может использоваться как в выражении, так и в левой части оператора присваивания = .
Если ключ _KeyVal отсутствует в контейнере, и операция [] используется в левой части оператора присваивания, создается ключ с соответствующим значением.

Пример.

#include iostream> #include map> using namespace std; void main() < // Операторная функция operator[] - переопределение оператора [] // 1. Создать контейнер через список инициализации initializer_listpairconst string, int>> lst = < make_pair("Jan", 31), make_pair("Feb", 28), make_pair("Mar", 31), make_pair("Apr", 30), make_pair("May", 31), make_pair("Jun", 30), make_pair("Jul", 31), make_pair("Aug", 31), make_pair("Sep", 30), make_pair("Oct", 31), make_pair("Nov", 30), make_pair("Dec", 31) >; mapstring, int> m1; m1.insert(lst); // 2. Получить количество дней в марте int d = m1["Mar"]; cout "d color: #008000;"> // 3. Изменить количество дней в феврале m1["Feb"] = 29; // 4. Проверка, изменено ли количество дней в феврале d = m1["Feb"]; // d = 29 cout "d color: #008000;"> // 5. Создать новую пару "ABCD":333 m1["ABCD"] = 333; // 6. Вывести массив mapstring, int>::iterator it = m1.begin(); cout "m1:" while (it != m1.end()) < cout first ":" second >
d = 31 d = 29 m1: ABCD:333 Apr:30 Aug:31 Dec:31 Feb:29 Jan:31 Jul:31 Jun:30 Mar:31 May:31 Nov:30 Oct:31 Sep:30

Связанные темы

  • Создание контейнера. Конструкторы. Создание пары. Обзор функций и операторов класса
  • Методы, изменяющие данные в контейнере: clear() , erase() , insert() , swap() , operator=()

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *