powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / map<char[10], char[40]> не могу откомпилировать
17 сообщений из 17, страница 1 из 1
map<char[10], char[40]> не могу откомпилировать
    #38450778
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изучаю map. Надо сделать ассоциативный массив с быстрым поиском элемента по ключу. Тут map идеально подходит.
Значение в реале будет не char[40], а структура такого же размера с инфой которую надо будет постоянно менять. (Если это принципиально).
Попробовал map<string, char[40]>
пример кода 1 (ключ string)
Код: 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.
#include "stdafx.h"
#pragma warning( disable : 4786)
#pragma warning( disable : 4996)
#include <windows.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <map>
#include <fstream>

using namespace std;

typedef struct {
	char szVal[40];
} sValue_t;

#define TEST_SIZE 1000000

int main()
{
	map <std::string, sValue_t> rows;
	char szKey[11];
	sValue_t sValue;
	std::string strKey;
	for(int i = 1; i < TEST_SIZE; i++)
	{
		sprintf(szKey, "%d", i);
		strKey = szKey;
		sprintf(sValue.szVal, "%039d", i);
		rows.insert(make_pair(strKey, sValue));
	}
	printf("Fill map %d element\n", TEST_SIZE);

	map <std::string, sValue_t>::iterator cur;
	cur = rows.find("12345");
	cout<<(*cur).first<<": "<<((*cur).second).szVal<<endl;
	Sleep(60000);
	return 0;
}


Отлично подходит. Быстро работает. НО жрет память не по-детски: данный пример забирает 110 мб на 1 млн.элементов. Полезной инфы около 47 мб (7 ключ + 40 моя инфа), остальные 63 мб получается служебная инфа. (Память диспетчером задач смотрел).

Попытался для ключа string заменить на char[10]
пример кода 2 (ключ char)
Код: 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.
55.
#include "stdafx.h"
#pragma warning( disable : 4786)
#pragma warning( disable : 4996)
#include <windows.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <map>
#include <fstream>

using namespace std;

typedef struct {
	char szKey[10];
} sKey_t;

typedef struct {
	char szVal[40];
} sValue_t;

struct clsCharCompare:
public                                 
binary_function<sKey_t, sKey_t, bool>
{ 
	bool operator() (const sKey_t& lhs, const sKey_t& rhs) const 
	{
		return strcmp(lhs.szKey, rhs.szKey) > 0;
	}
};

#define TEST_SIZE 1000000

int main()
{
	map <sKey_t, sValue_t, clsCharCompare> rows;
	sKey_t sKey;
	sValue_t sValue;
	for(int i = 1; i < TEST_SIZE; i++)
	{
		sprintf(sKey.szKey, "%d", i);
		sprintf(sValue.szVal, "%039d", i);
		rows.insert(make_pair(sKey, sValue));
	}
	printf("Fill map %d element\n", TEST_SIZE);

	map <std::string, sValue_t>::iterator cur;
	sKey_t sFindKey = {"12345"};
	rows.find(sFindKey); // Это работает
	
	//cur = rows.find(sFindKey); // Это не компилируется
	//cout<<((*cur).first).szKey<<": "<<((*cur).second).szVal<<endl;

	Sleep(60000);
	return 0;
}


Память расходует экономнее: занимает 80 мб из них 50 полезная инфа, 30 служебная.
Но тут начались проблемы с компиляцией:
как задать функцию сравнения ключей я разобрался (clsCharCompare) в результате чего даже заполнить получилось, но дальше какой-то взрыв мозга начинается. В инете ничего подобного не нашел.

При компиляции, на строке
Код: plaintext
1.
cur = rows.find(sFindKey);


выдает ошибку
error C2679 binary '=' : no operator found which takes a right-hand operand of type ...error C2679: binary '=' : no operator found which takes a right-hand operand of type 'std::_Tree<_Traits>::iterator' (or there is no acceptable conversion)
1> with
1> [
1> _Traits=std::_Tmap_traits<sKey_t,sValue_t,clsCharCompare,std::allocator<std::pair<const sKey_t,sValue_t>>,false>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\xtree(498): could be 'std::_Tree<_Traits>::iterator &std::_Tree<_Traits>::iterator::operator =(const std::_Tree<_Traits>::iterator &)'
1> with
1> [
1> _Traits=std::_Tmap_traits<std::string,sValue_t,std::less<std::string>,std::allocator<std::pair<const std::string,sValue_t>>,false>
1> ]
1> while trying to match the argument list '(std::_Tree<_Traits>::iterator, std::_Tree<_Traits>::iterator)'
1> with
1> [
1> _Traits=std::_Tmap_traits<std::string,sValue_t,std::less<std::string>,std::allocator<std::pair<const std::string,sValue_t>>,false>
1> ]
1> and
1> [
1> _Traits=std::_Tmap_traits<sKey_t,sValue_t,clsCharCompare,std::allocator<std::pair<const sKey_t,sValue_t>>,false>
1> ]

причем так компилируется
Код: plaintext
1.
rows.find(sFindKey);


Как понимаю - не прописано как выполнить = для моей структуры sKey_t , но как и куда это прописывать никак не могу сообразить :(
Может функция какая-то есть взамен =

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

Помогите запустить второй пример или дайте ссылку на что-то похожее.
...
Рейтинг: 0 / 0
map<char[10], char[40]> не могу откомпилировать
    #38450779
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Немного накосячил во втором примере. Вместо
Код: plaintext
1.
map <std::string, sValue_t>::iterator cur;


надо
Код: plaintext
1.
map <sKey_t, sValue_t>::iterator cur;


Но проблему мою это никак не решает.
...
Рейтинг: 0 / 0
map<char[10], char[40]> не могу откомпилировать
    #38450825
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,

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

Чтобы не извращаться, обычно пишут так:
Код: plaintext
1.
2.
3.
typedef  ... map_t;
map_t map;
map_t::iterator it = map.find(...);
...
Рейтинг: 0 / 0
map<char[10], char[40]> не могу откомпилировать
    #38450847
boost
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dima TНО жрет память не по-детски: данный пример забирает 110 мб на 1 млн.элементов. Полезной инфы около 47 мб (7 ключ + 40 моя инфа), остальные 63 мб получается служебная инфа. (Память диспетчером задач смотрел).


Для таких размеров лучше подходит boost::intrusive
...
Рейтинг: 0 / 0
map<char[10], char[40]> не могу откомпилировать
    #38450851
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,

Отлично подходит. Быстро работает. НО жрет память не по-детски: данный пример забирает 110 мб на 1 млн.элементов. Полезной инфы около 47 мб (7 ключ + 40 моя инфа), остальные 63 мб получается служебная инфа. (Память диспетчером задач смотрел).

map имеет некоторые накладные расходы.
Если нужно их избежать, нужно хранить данные в сортированном векторе и искать по нему бинарным поиском.
...
Рейтинг: 0 / 0
map<char[10], char[40]> не могу откомпилировать
    #38450927
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivmap имеет некоторые накладные расходы.
Это я понял и второй вариант меня устроит, но он не работает. Точнее map я наполнил, осталось что-то дописать, чтоб извлекать найденное. Насколько сложно это допилить?
MasterZivЕсли нужно их избежать, нужно хранить данные в сортированном векторе и искать по нему бинарным поиском.
Так и написал, только без вектора: кусок памяти и там сортированный массив структур. Бинарный поиск работает в два раза быстрее поиска map`а, но заполнение в 670 раз медленнее (0,7 сек против 470 сек.) (вставки в основном в середину), что и ожидалось, т.к. realloc() и memcpy() не быстрые.
Попробую на вектор переписать, хотя бы код будет читабельнее. Хотя возможно мой исходный вариант быстрее будет (я realloc() немного оптимизировал, сделал чтоб сразу +50% памяти добавлял).
Запустил тест вектора: заполнение вектора 1 млн. элементов со вставкой каждого в середину. Минут 20 уже молотит. Не уверен что с ним лучше будет.

Прикинул тут статистику по времени: получается что мне будет map выгоднее если каждый элемент потребуется искать менее 6000 раз. У меня по плану 100-200 в сутки в среднем. Так что мне map желательно использовать.
...
Рейтинг: 0 / 0
map<char[10], char[40]> не могу откомпилировать
    #38450937
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
boostДля таких размеров лучше подходит boost::intrusive
А какая разница с точки зрения расхода памяти, где будет храниться обвязка узлов мэпа, в узле(как в intrusive) или снаружи узла (как в std)?
...
Рейтинг: 0 / 0
map<char[10], char[40]> не могу откомпилировать
    #38450938
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TMasterZivЕсли нужно их избежать, нужно хранить данные в сортированном векторе и искать по нему бинарным поиском.
Так и написал, только без вектора: кусок памяти и там сортированный массив структур. Бинарный поиск работает в два раза быстрее поиска map`а, но заполнение в 670 раз медленнее (0,7 сек против 470 сек.) (вставки в основном в середину), что и ожидалось, т.к. realloc() и memcpy() не быстрые.
Так вы не вставляйте в середину. Дописывайте в конец, а потом все за один раз отсортируйте.
...
Рейтинг: 0 / 0
map<char[10], char[40]> не могу откомпилировать
    #38450996
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyТак вы не вставляйте в середину. Дописывайте в конец, а потом все за один раз отсортируйте.
Знаю что отсортировать можно, но надо сразу в середину, т.к. элементы будут появляться/исчезать асинхронно в процессе работы.
Задачу я в итоге все равно решу, алгоритмами или деньгами (будет работать у провайдера на VDSе), но хочется алгоритмами ограничится :)

Мне кажется что я почти решил мою проблему, оптимально устраивающим меня способом, остались какие-то мелочи в допиливании второго примера.
пример кода 2 (ключ char)
Код: 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.
55.
#include "stdafx.h"
#pragma warning( disable : 4786)
#pragma warning( disable : 4996)
#include <windows.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <map>
#include <fstream>

using namespace std;

typedef struct {
	char szKey[10];
} sKey_t;

typedef struct {
	char szVal[40];
} sValue_t;

struct clsCharCompare:
public                                 
binary_function<sKey_t, sKey_t, bool>
{ 
	bool operator() (const sKey_t& lhs, const sKey_t& rhs) const 
	{
		return strcmp(lhs.szKey, rhs.szKey) > 0;
	}
};

#define TEST_SIZE 1000000

int main()
{
	map <sKey_t, sValue_t, clsCharCompare> rows;
	sKey_t sKey;
	sValue_t sValue;
	for(int i = 1; i < TEST_SIZE; i++)
	{
		sprintf(sKey.szKey, "%d", i);
		sprintf(sValue.szVal, "%039d", i);
		rows.insert(make_pair(sKey, sValue));
	}
	printf("Fill map %d element\n", TEST_SIZE);

	map <sKey_t, sValue_t>::iterator cur;
	sKey_t sFindKey = {"12345"};
	rows.find(sFindKey); // Это работает
	
	//cur = rows.find(sFindKey); // Это не компилируется
	//cout<<((*cur).first).szKey<<": "<<((*cur).second).szVal<<endl;

	Sleep(60000);
	return 0;
}


Или я ошибаюсь и там еще писать и писать?
...
Рейтинг: 0 / 0
map<char[10], char[40]> не могу откомпилировать
    #38450997
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Используй хэш-таблицу вместо вектора и будет тебе счастье.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
map<char[10], char[40]> не могу откомпилировать
    #38451029
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,

А какая проблема-то?
...
Рейтинг: 0 / 0
map<char[10], char[40]> не могу откомпилировать
    #38451161
boost
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly MoskovskyboostДля таких размеров лучше подходит boost::intrusive
А какая разница с точки зрения расхода памяти, где будет храниться обвязка узлов мэпа, в узле(как в intrusive) или снаружи узла (как в std)?
У intrusive есть несколько преимуществ хорошо заметных на больших размерах.

IssueIntrusiveNon-intrusiveMemory managementExternalInternal through allocatorInsertion/Erasure timeFasterSlowerMemory localityBetterWorseCan hold non-copyable and non-movable objects by valueYesNoException guaranteesBetterWorseComputation of iterator from valueConstantNon-constantInsertion/erasure predictabilityHighLowMemory useMinimalMore than minimalInsert objects by value retaining polymorphic behaviorYesNo (slicing)
...
Рейтинг: 0 / 0
map<char[10], char[40]> не могу откомпилировать
    #38451180
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
boostMemory useMinimalMore than minimal
Так я и спрашиваю, для мэпа в чем конкретно разница?
Я лично ее не вижу.
...
Рейтинг: 0 / 0
map<char[10], char[40]> не могу откомпилировать
    #38451184
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyDima T,

А какая проблема-то?
Такая
error C2679: binary '=' : no operator found which takes a right-hand operand of type 'std::_Tree<_Traits>::iterator' (or there is no acceptable conversion)

В первом посте написал:
Dima T Как понимаю - не прописано как выполнить = для моей структуры sKey_t , но как и куда это прописывать никак не могу сообразить :(
Может функция какая-то есть взамен =

С синтаксисом С++ у меня проблемы: вроде понятно в целом, разберусь, если пример похожий есть. Но на данный случай ничего похожего не нашел.
...
Рейтинг: 0 / 0
map<char[10], char[40]> не могу откомпилировать
    #38451280
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TAnatoly MoskovskyDima T,

А какая проблема-то?
Такая
error C2679: binary '=' : no operator found which takes a right-hand operand of type 'std::_Tree<_Traits>::iterator' (or there is no acceptable conversion)

В первом посте написал:
Dima T Как понимаю - не прописано как выполнить = для моей структуры sKey_t , но как и куда это прописывать никак не могу сообразить :(
Может функция какая-то есть взамен =

С синтаксисом С++ у меня проблемы: вроде понятно в целом, разберусь, если пример похожий есть. Но на данный случай ничего похожего не нашел.
А вы исправили то что я вам первым же сообщением написал?
Anatoly MoskovskyМэп, от которого берется тип итератора, должен быть точно тем же что и для самого контейнера.
А у вас в типе итератора отсутствует компаратор.

Чтобы не извращаться, обычно пишут так:
Код: plaintext
1.
2.
3.
typedef  ... map_t;
map_t map;
map_t::iterator it = map.find(...);
...
Рейтинг: 0 / 0
map<char[10], char[40]> не могу откомпилировать
    #38451295
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyА у вас в типе итератора отсутствует компаратор.
Я тормоз :)
Сразу не понял о чем речь.
Сейчас заработало.
Спасибо.
...
Рейтинг: 0 / 0
map<char[10], char[40]> не могу откомпилировать
    #38451303
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Замерил скорость. Летает map<char[10], char[40]>, моя поделка тормоз по сравнению с ним :)
По сравнению map<string, char[40]>:
Заполнение вдвое быстрее
Поиск в 6 раз быстрее (в 3 раза быстрее моего самодельного)

Тут лишние 30 байт на один элемент стоят того чтоб их задействовать.
...
Рейтинг: 0 / 0
17 сообщений из 17, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / map<char[10], char[40]> не могу откомпилировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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