powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / map и прочее
24 сообщений из 24, страница 1 из 1
map и прочее
    #39259283
Sp999
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Доброго времени суток всем!

Сорри заранее за возможно тупой вопрос, но что-то я в контейнерах недопонял...
Подскажите плиз вот какую вещь: если я хочу завести map, парой ключ-значение у которого будет строка и еще какой-нибудь контейнер (вектор или множество), то каким образом мне добавлять в него элементы? Как должна выглядеть команда вставки в карту пустого вектора или множества?

С уважением, Валера.
...
Рейтинг: 0 / 0
map и прочее
    #39259286
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
my_map[key] = my_vector;
...
Рейтинг: 0 / 0
map и прочее
    #39259288
Sp999
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T
Код: plaintext
1.
my_map[key] = my_vector;


В этом случае должна существовать переменная
Код: plaintext
1.
vector<T> my_vector;


А вот если мне надо вставить несколько записей, то я должен создать несколько таких переменных (или даже массив из них)?
Зачастую задача стоит таким образом, что неизвестно заранее, сколько элементов будет содержать карта...
...
Рейтинг: 0 / 0
map и прочее
    #39259293
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не надо массивов, там копирование происходит, поэтому можно так
Код: plaintext
1.
2.
3.
4.
vector<T> my_vector;
my_map[key1] = my_vector;
my_map[key2] = my_vector;
...
...
Рейтинг: 0 / 0
map и прочее
    #39259295
Sp999
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TНе надо массивов, там копирование происходит, поэтому можно так
Код: plaintext
1.
2.
3.
4.
vector<T> my_vector;
my_map[key1] = my_vector;
my_map[key2] = my_vector;
...


Тогда вдогонку еще один вопрос. Вот карта создана и заполнена таким образом. Как теперь дозаполнять включенные в нее векторы?
...
Рейтинг: 0 / 0
map и прочее
    #39259299
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Точно так же как с массивом.

Если изначально заполняешь пустыми, то можно вообще не заполнять, т.к. как только впервые обратишься my_map[key] то автоматом создастся новый элемент, если его не существует.
...
Рейтинг: 0 / 0
map и прочее
    #39259300
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тут почитай . В описаниях методов есть примеры.
...
Рейтинг: 0 / 0
map и прочее
    #39259304
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sp999Как теперь дозаполнять включенные в нее векторы?
Как вариант
Код: plaintext
1.
my_map[key].push_back(N);


если надо много обращений подряд, то лучше получить указатель на my_map[key] и работать с указателем, чтобы поиск каждый раз не происходил.

Про vector
...
Рейтинг: 0 / 0
map и прочее
    #39259306
Sp999
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Что-то все равно у меня не выходит... Заполняю структуру, потом вывожу на экран - получаю пустые группы. Что я делаю не так?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
#include <iostream>
#include <set>
#include <map>
#include <string>
#include <algorithm>

using namespace std;
#define StrSet multiset<char *>
#define MyMap map<unsigned long, StrSet&>

// Создание структуры для хранения студенческих групп, группы имеют свой номер и должны быть упорядочены по нему,
// каждая группа содержит фамилии студентов в алфавитном порядке (могут быть дубли)

void main() {
	setlocale(LC_ALL, "Russian");

	unsigned long num_group = 1;
	char str[50];
	unsigned long val;
	char* end_ptr;
	MyMap secondMap;
	StrSet mySet;
        // Ввод данных и заполнение структуры
	do {
		cout << "Введите фамилию студента группы " << num_group << " или номер новой группы (0 - для выхода): ";
		cin >> str;
		val = strtoul(str, &end_ptr, 10);
		cout << val << endl;
		if(*end_ptr) {
			if(secondMap.find(num_group) == secondMap.end()) { // если группы с таким номером нет, то создаем новый элемент
				secondMap.insert(pair<unsigned long, StrSet&>(num_group, mySet));
			}
                        // добавляем в множество этой группы новую фамилию
			StrSet(secondMap.find(num_group)->second).insert(str);
			val = 1;
		}
		else if ((val == LONG_MAX || val == LONG_MIN) && errno == ERANGE) {
			break;
		}
		else {
			num_group = val;
		}
	} while (val != 0);
        // Вывод полученной структуры
	for(MyMap::const_iterator it = secondMap.begin(); it != secondMap.end(); ++it) {
		StrSet sv = (StrSet)(it->second);
		cout << it->first << ":";
		for(StrSet::const_iterator it2 = sv.begin(); it2 != sv.end(); ++it2) {
			cout << " " << *it2;
		}
		cout << endl;
	}
	system("pause");
}
...
Рейтинг: 0 / 0
map и прочее
    #39259313
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sp999Что-то все равно у меня не выходит... Заполняю структуру, потом вывожу на экран - получаю пустые группы. Что я делаю не так?
Код: plaintext
1.
2.
#define StrSet multiset<char *>
#define MyMap map<unsigned long, StrSet&>


Если используешь указатели и ссылки, то сам заботься о размещении в памяти своих данных.
Так будет работать
Код: plaintext
1.
2.
#define StrSet multiset<string>
#define MyMap map<unsigned long, StrSet>


лучше так писать
Код: plaintext
1.
2.
typedef multiset<string> StrSet_t;
typedef map<unsigned long, StrSet_t> MyMap_t;
...
Рейтинг: 0 / 0
map и прочее
    #39259335
Sp999
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TSp999Что-то все равно у меня не выходит... Заполняю структуру, потом вывожу на экран - получаю пустые группы. Что я делаю не так?
Код: plaintext
1.
2.
#define StrSet multiset<char *>
#define MyMap map<unsigned long, StrSet&>


Если используешь указатели и ссылки, то сам заботься о размещении в памяти своих данных.
Так будет работать
Код: plaintext
1.
2.
#define StrSet multiset<string>
#define MyMap map<unsigned long, StrSet>


лучше так писать
Код: plaintext
1.
2.
typedef multiset<string> StrSet_t;
typedef map<unsigned long, StrSet_t> MyMap_t;


Переписал все с использованием последнего варианта - проблема осталась...
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
#include <iostream>
#include <set>
#include <map>
#include <string>
#include <algorithm>

using namespace std;
typedef multiset<string> StrSet_t;
typedef map<unsigned long, StrSet_t> MyMap_t;

void main() {
	setlocale(LC_ALL, "Russian");

	unsigned long num_group = 1;
	string str;
	MyMap_t secondMap;
	StrSet_t mySet;
	for(int i = 0; i < 3; i++) {
		cout << "Введите фамилию студента группы " << num_group << ": ";
		cin >> str;
		if(secondMap.find(num_group) == secondMap.end()) {
			secondMap.insert(pair<unsigned long, StrSet_t>(num_group, mySet));
		}
		StrSet_t(secondMap.find(num_group)->second).insert(str);
	}
        // Вывод полученной структуры
	for(MyMap_t::const_iterator it = secondMap.begin(); it != secondMap.end(); ++it) {
		StrSet_t sv = (StrSet_t)(it->second);
		cout << it->first << ":";
		for(StrSet_t::const_iterator it2 = sv.begin(); it2 != sv.end(); ++it2) {
			cout << " " << *it2;
		}
		cout << endl;
	}
	system("pause");
}
...
Рейтинг: 0 / 0
map и прочее
    #39259343
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sp999Переписал все с использованием последнего варианта - проблема осталась...
Код: plaintext
1.
		StrSet_t(secondMap.find(num_group)->second).insert(str);


Это ерунда какая-то, надо так
Код: plaintext
1.
secondMap.find(num_group)->second.insert(str);


еще проще заменить
Код: plaintext
1.
2.
3.
4.
		if (secondMap.find(num_group) == secondMap.end()) {
			secondMap.insert(pair<unsigned long, StrSet_t>(num_group, mySet));
		}
		secondMap.find(num_group)->second.insert(str);


на
Код: plaintext
1.
secondMap[num_group].insert(str);



Косяки при выводе:
Код: plaintext
1.
StrSet_t sv = (StrSet_t)(it->second);


это создание копии и явное приведение типов, никогда не используй его без острой необходимости.

Вообще это лишнее, работай с исходным объектом
Код: plaintext
1.
2.
3.
4.
5.
...
		//StrSet_t sv = (StrSet_t)(it->second);
		cout << it->first << ":";
		for (StrSet_t::const_iterator it2 = it->second.begin(); it2 != it->second.end(); ++it2) {
...
...
Рейтинг: 0 / 0
map и прочее
    #39259351
Sp999
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TSp999Переписал все с использованием последнего варианта - проблема осталась...
Код: plaintext
1.
		StrSet_t(secondMap.find(num_group)->second).insert(str);


Это ерунда какая-то, надо так
Код: plaintext
1.
secondMap.find(num_group)->second.insert(str);


еще проще заменить
Код: plaintext
1.
2.
3.
4.
		if (secondMap.find(num_group) == secondMap.end()) {
			secondMap.insert(pair<unsigned long, StrSet_t>(num_group, mySet));
		}
		secondMap.find(num_group)->second.insert(str);


на
Код: plaintext
1.
secondMap[num_group].insert(str);



Косяки при выводе:
Код: plaintext
1.
StrSet_t sv = (StrSet_t)(it->second);


это создание копии и явное приведение типов, никогда не используй его без острой необходимости.

Вообще это лишнее, работай с исходным объектом
Код: plaintext
1.
2.
3.
4.
5.
...
		//StrSet_t sv = (StrSet_t)(it->second);
		cout << it->first << ":";
		for (StrSet_t::const_iterator it2 = it->second.begin(); it2 != it->second.end(); ++it2) {
...


Фантастика! Заработало! Спасибо огромное!
Остался для меня только один неразрешенным вопрос: как красиво можно проверить, что в строку (string str) ввели число?
...
Рейтинг: 0 / 0
map и прочее
    #39259663
alexy_black
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
"ключи! ключи же есть!" ©
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
#include <iostream>
#include <vector>
#include <map>

typedef std::vector<std::string> strings_t;
typedef std::map<unsigned int,strings_t> groups_t;

int main(int argc, char** argv) {
    groups_t students_groups;
    for(int i=0;i<=6;i++) {
        unsigned int cur_group = i%2;
        std::string student;
        std::cout << "input please for gourp " << cur_group << ": " ;
        std::cin >> student;
        students_groups[cur_group].push_back(student);
        std::cout << std::endl;
    }

    for(auto group:students_groups) {
        std::cout << group.first << ':';
        for(auto student:group.second) std::cout << " " << student;
        std::cout << std::endl;
    }

    return 0;
}



http://en.cppreference.com/w/cpp/string/byte/isdigit
...
Рейтинг: 0 / 0
map и прочее
    #39259680
alexy_black
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sp999,

чтобы разбираться в собственных программах через пару месяцев после написания вам необходимо использовать std:: а не писать using namespace std; это оченоь плохая практика.

также нужно привыкнуть давать читаемые и занчащие имена переменным. к примеру в моем коде было бы трудно понять что значит i%2 если бы не было переменной cur_group. а с ней понятно, что я хотел получить номер группы.
...
Рейтинг: 0 / 0
map и прочее
    #39259895
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TНе надо массивов, там копирование происходит, поэтому можно так
Код: plaintext
1.
2.
3.
4.
vector<T> my_vector;
my_map[key1] = my_vector;
my_map[key2] = my_vector;
...




можно также использовать initializer list
...
Рейтинг: 0 / 0
map и прочее
    #39260024
Пётр Седов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alexy_blackчтобы разбираться в собственных программах через пару месяцев после написания вам необходимо использовать std:: а не писать using namespace std; Спорно.

alexy_blackэто оченоь плохая практика.В .h-файлах -- плохая практика, а в .cpp-файлах -- нормальная.
...
Рейтинг: 0 / 0
map и прочее
    #39260042
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пётр СедовВ .h-файлах -- плохая практика, а в .cpp-файлах -- нормальная.
На самом деле в хедерах тоже можно без проблем использовать.
Внутри неймспейсов.
...
Рейтинг: 0 / 0
map и прочее
    #39260199
alexy_black
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пётр Седов,

ну.. предположим есть переменная, которая содрежит какю-то карту.. как её назвать? map? но если использовать std, то выходит что нельзя.

чтобы меньше писать я обычно делаю что-то вроде namespace pl=std::placeholders; а вот чтобы std:: не дописывать..

у меня обычно есть файлы с исключениями. там всего сторок 30-50. вот может в таком файле и можно написать using namespace std..

почему я говорю что это плохая практика: пользы от этого нет (думаю, что если плохо печатаешь, то нужно учиться этому на тренажорах, а не упрощать себе задачу такими способами). если я просто не заметил пользы, то укажите пожалуйста. а вот вред может быть. по крайней мере читать становиться трудно. вот mutex например. так можно назвать переменную класса, можно статическую переменную в фукнции, а может это std::mutex - название типа. как определить не вникая в контекст?
также когда забудешь, что указал using namespace std или просто не знаешь какого-то аспекта стандартной библиотеки, то может возникнуть конфликт имен..
...
Рейтинг: 0 / 0
map и прочее
    #39260316
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alexy_blackвот mutex например. так можно назвать переменную класса
Для членов класса обычно приняты префиксы/суффиксы.
А внутри функции используйте auto вместо типа. В крайнем случае если действительно нужен тип а уже есть переменная с этим именем, то тогда и добавьте std::, в этом одном месте, а не во всем проекте.

Короче проблема с using namespace std высосана из пальца.
Я участвовал в проектах в которых стандарт кодирования как разрешал так и запрещал это. И никакой практической разницы не заметил.
Поэтому каждый сам решает.
...
Рейтинг: 0 / 0
map и прочее
    #39260691
alexy_black
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyДля членов класса обычно приняты префиксы/суффиксы.
А внутри функции используйте auto вместо типа. В крайнем случае если действительно нужен тип а уже есть переменная с этим именем, то тогда и добавьте std::, в этом одном месте, а не во всем проекте. как auto использовать?
Код: plaintext
1.
2.
3.
4.
void foo() {
  static auto mutex; // :)
  std::lock_guard<auto> lock(mutex); // :)
}

на счет того, что бы использовать std где нужно, то так можно. я говорил о читаемости, а не о невозможности. это вводит больше упорядочности..

Anatoly MoskovskyКороче проблема с using namespace std высосана из пальца.
Я участвовал в проектах в которых стандарт кодирования как разрешал так и запрещал это. И никакой практической разницы не заметил.
Поэтому каждый сам решает.вобще тут наверное главное действительно следовать стандарту проекта (как и во многом другом).

ps: холивар :)
...
Рейтинг: 0 / 0
map и прочее
    #39260744
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alexy_blackкак auto использовать?
Код: plaintext
1.
2.
3.
4.
void foo() {
  static auto mutex; // :)
  std::lock_guard<auto> lock(mutex); // :)
}



Тут не надо auto. В С/С++ можно писать так.
Код: plaintext
1.
  mutex mutex; 
...
Рейтинг: 0 / 0
map и прочее
    #39261437
Пётр Седов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alexy_black, мне не нравится код, в котором на каждом углу «std::string», этот «std::» захламляет код. А представьте, если бы надо было писать «std::int», «std::double», это была бы полная Ѡ.
...
Рейтинг: 0 / 0
map и прочее
    #39262128
alexy_black
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пётр Седовalexy_black, мне не нравится код, в котором на каждом углу «std::string», этот «std::» захламляет код. А представьте, если бы надо было писать «std::int», «std::double», это была бы полная Ѡ.это вы привыкли.. я вот видел код в котором был вывод в cout (без std). вот вы подумали это куда вывод? просто я уже читал код этого автора и он никогда не писал using namespace std; так что я понял, что это какой-то другой cout. так и оказалось. еще я видел код где был другой string..
когда я смотрю на код, то я не читаю выражения по типу "std::string" я их узнаю. поэтому получается быстро, даже с лишними пятью символами.

тут дело еще в том, что код будут читать другие. они не знают о стандартах писавшего. например когда я отлаживаю какой-нибудь код, иногда заглядываю в библиотеки. там оказываюсь сразу посредине какого-то файла (под отладчиком). если я вижу std::string - то все понятно. если я вижу string some="hello" - то что это? мне нужно посмотреть в начале файла не сказал ли он там using namespace std; или может он вобще в заголовке указал его каком-нибудь.. пойди разберись.

код должен смотреться просторно не за счет того, что сокращаешь имена переменных и названий типов, а за счет того, что хорош разбиваешь по функциям с говорящими именами.


да, к счастью многие редакторы подсвечивают поды :)
...
Рейтинг: 0 / 0
24 сообщений из 24, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / map и прочее
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]