std::map - n-й элемент массива
От: Аноним  
Дата: 28.04.03 11:29
Оценка:
Как получить n-й элемент массива в std::map?

например:

Привет!

Не знаешь как мне достучаться
до n-ого элемента в std::map?


typedef std::map<int, std::string> ITEMS;
typedef std::map<int,std::string>::const_iterator CI_I;

ITEMS m_Items;

/*
Инициализация m_Items
*/

CI_I p=m_Items.begin();  ///первый
++p; // второй
p = m_Items.end(); //последний


а n-ый?
Re: std::map - n-й элемент массива
От: Sergeem Израиль  
Дата: 28.04.03 11:32
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Как получить n-й элемент массива в std::map?

...

А>а n-ый?


а зачем, спрашивается?
Serge.

Hасколько проще была бы жизнь, если бы она была в исходниках.
Re: std::map - n-й элемент массива
От: Bell Россия  
Дата: 28.04.03 11:35
Оценка: +1
Здравствуйте, Аноним, Вы писали:

А>Как получить n-й элемент массива в std::map?



А>
А>typedef std::map<int, std::string> ITEMS;
А>typedef std::map<int,std::string>::const_iterator CI_I;

А>ITEMS m_Items;

А>/*
А>Инициализация m_Items
А>*/

А>CI_I p=m_Items.begin();  ///первый
А>++p; // второй
А>p = m_Items.end(); //Следующий за последним
А>


А>а n-ый?


int n = ...;
std::map<int,std::string>::iterator it = mItems.begin();//it - неконстантный итератор
std::advance(it, n);


Сложность — линейная. Вообще подобные операции плохо подходят для map — опиши подробнее, почему такая необходимость возникает.
Любите книгу — источник знаний (с) М.Горький
Re: std::map - n-й элемент массива
От: Дмитрий Наумов  
Дата: 28.04.03 11:37
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>как мне достучаться до n-ого элемента в std::map?


Вообще то можешь использовать std::advance, но это будет невыгодно — сложность линейная. Может тебе совсем не map нужно было использовать?
... << RSDN@Home 1.0 beta 6a >>

Удалено избыточное цитирование. -- ПК
Re[2]: std::map - n-й элемент массива
От: Аноним  
Дата: 28.04.03 11:50
Оценка:
Здравствуйте, Дмитрий Наумов.
Здравствуйте, Sergeem.
Здравствуйте, Bell.


Вы вкратце писали:
А> А зачем тебе это нужно?


Это нужно для хранения элементов разрабатываемого
мной ComboBox — а. А именно строки + ассоциированного с ней числового значения.

А n-ый элемент нужен например при выборе в
ListBox-е строки и занесения ее в Edit
Re[3]: std::map - n-й элемент массива
От: Дмитрий Наумов  
Дата: 28.04.03 12:12
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Здравствуйте, Дмитрий Наумов.

А>Здравствуйте, Sergeem.
А>Здравствуйте, Bell.

А>

А>Вы вкратце писали:
А>> А зачем тебе это нужно?

А>

А>Это нужно для хранения элементов разрабатываемого
А>мной ComboBox — а. А именно строки + ассоциированного с ней числового значения.

Методы ComboBox'a SetItemData/GetItemData дают тебе возможность ассоциировать некое числовое значение со строкой и без использования std::map

А>А n-ый элемент нужен например при выборе в

А>ListBox-е строки и занесения ее в Edit

Имхо, если тебе не хватает ассоциированного значения (см. пункт выше), то тебе нужен вектор и тогда номер строки будет индексом в векторе. Применение std::map не выглядит оправданным.
... << RSDN@Home 1.0 beta 6a >>
Re[3]: std::map - n-й элемент массива
От: Михаил Можаев Россия www.mozhay.chat.ru
Дата: 28.04.03 12:15
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Это нужно для хранения элементов разрабатываемого

А>мной ComboBox — а. А именно строки + ассоциированного с ней числового значения.

Это можно вообще без map сделать. Ассоциированные числовые значения проще хранить прямо в ComboBox:

c_combo.SetItemData(c_combo.AddString("String1"), associated_value);
associated_value = c_combo.GetItemData(c_combo.GetCurSel());
... << RSDN@Home 1.0 beta 6a >>
Re[4]: std::map - n-й элемент массива
От: Аноним  
Дата: 28.04.03 12:49
Оценка:
Здравствуйте, Михаил Можаев
Дмитрий Наумов,

Вы вкратце писали:



ДН>Методы ComboBox'a SetItemData/GetItemData дают тебе возможность ассоциировать некое числовое значение со строкой и без использования std::map



ДН>Это можно вообще без map сделать. Ассоциированные числовые значения проще хранить прямо в ComboBox:

ДН>c_combo.SetItemData(c_combo.AddString("String1"), associated_value);
ДН>associated_value = c_combo.GetItemData(c_combo.GetCurSel());


Именно это я и хочу реализовать в разрабатываемом мною ComboBox-е .
Я не использую ни MFC ни даже Win32. =)


Дмитрий Наумов,
Вы писали:

ДН>Имхо, если тебе не хватает ассоциированного значения (см. пункт выше), то тебе нужен вектор и тогда номер строки будет индексом в векторе. Применение std::map не выглядит оправданным.


По началу я и использовал std::vector. До тех пор пока мне не понадобилось
ассоциировать с каждым элементом ComboBoxa еще и числовое значение
(не индекс элемента в ListBox-е)

Сложнее говоря со строкой я ассоциирую 2 числовых значения —
1ое — это порядок следования строк в ListBox-е
2е — это просто число ассоциируемое со строкой.

Так вот 1-е и есть номер элемента в массиве.

Это можно реализовать хтоябы так:


typedef std::map<int, std::string> ITEMS;
typedef std::map<int,std::string>::const_iterator CI_I;

ITEMS m_Items;

/*
Инициализация m_Items
*/

CI_I p=m_Items.begin();  ///первый

int n=7; //элемент массива

for(int i=0;i<n; i++)
    p++;

std::string str = p->second;  // это и есть 7-й элемент массива
int itemdata = p->first;     // а это число ассоциированное с ним


Но ведь состоявшиеся программисты так не пишут. =)
некрасиво — с!

Вот я и спрашиваю как же зто сделать правильно (крассиво).
Re[5]: std::map - n-й элемент массива
От: MaximE Великобритания  
Дата: 28.04.03 12:58
Оценка: :)
Здравствуйте, <Аноним>, Вы писали:

А>Именно это я и хочу реализовать в разрабатываемом мною ComboBox-е .

А>Я не использую ни MFC ни даже Win32. =)

ComboBox для консоли?
Re[5]: std::map - n-й элемент массива
От: Дмитрий Наумов  
Дата: 28.04.03 13:00
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Сложнее говоря со строкой я ассоциирую 2 числовых значения —

А>1ое — это порядок следования строк в ListBox-е
А>2е — это просто число ассоциируемое со строкой.

А>Так вот 1-е и есть номер элемента в массиве.


А>Это можно реализовать хтоябы так: <...>


А>Но ведь состоявшиеся программисты так не пишут. =) некрасиво — с!

А>Вот я и спрашиваю как же зто сделать правильно (крассиво).

А вот так слабо?
struct ComboboxEntry
{
    std::string text;   // сама строка
    int cookie;         // ассоциированное с ней значение
};


Дальше эту структуру храним или в векторе или в мапе.
... << RSDN@Home 1.0 beta 6a >>

Удалено избыточное цитирование. -- ПК.
Re[6]: std::map - n-й элемент массива
От: Аноним  
Дата: 28.04.03 13:19
Оценка:
Дмитрий Наумов, Вы писали:
ДН>А что же тогда?

Здравствуйте, MaximE, Вы писали:
ДН>ComboBox для консоли?

DirectX.


А>Дмитрий Наумов,

А>Вы писали:

ДН>А вот так слабо?

ДН>
ДН>struct ComboboxEntry
ДН>{
ДН>    std::string text;   // сама строка
ДН>    int cookie;         // ассоциированное с ней значение
ДН>};
ДН>


ДН>Дальше эту структуру храним или в векторе или в мапе.



Нет не слабо. Это один из вариантов...
Но вопрос то был не по алгоритму реализации,
а по STL. Неужели там не реализована такая элементарная функциональнось???

Если нет то хотелось бы спросить знатоков STL как же ее реализовать
по правилам того самого STL?
Re[7]: std::map - n-й элемент массива
От: Дмитрий Наумов  
Дата: 28.04.03 13:25
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>вопрос то был не по алгоритму реализации, а по STL. Неужели там не реализована такая элементарная функциональнось???


А>Если нет то хотелось бы спросить знатоков STL как же ее реализовать по правилам того самого STL?


Как уже тебе сказали, используй std::advance. Один из принципов STL — не выносить в методы контейнера то, что заведомо будет неэффективно для данного контейнера. operator[] для вектора эффективен, для map — нет.
... << RSDN@Home 1.0 beta 6a >>

Удалено избыточное цитирование. -- ПК.
Re[7]: std::map - n-й элемент массива
От: Михаил Можаев Россия www.mozhay.chat.ru
Дата: 28.04.03 14:07
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>а по STL. Неужели там не реализована такая элементарная функциональнось???

А>Если нет то хотелось бы спросить знатоков STL как же ее реализовать
А>по правилам того самого STL?

По правилам STL — std::advance. Но возможны проблемы с производительностью. Хотя, если элементов меньше 100, то это заметно не будет, тем более, что комбобокс нужен для пользовательского интерфейса, а там это будет незаметно, т.к. пользователь тормозит гораздо сильнее.

Кроме того, этот доступ по индексу не будет иметь смысла, если в процессе работы добавлять или удалять пункты. Т.к. при изменении map'а индексы могут поползти.

Есть вариант — 2 map'а. Один — <string, int>, второй — <int, string>
Правда, заполнять дольше. Но заполнение делается один раз, так что ради скорости работы можно пойти на это.
... << RSDN@Home 1.0 beta 6a >>
Re[8]: std::map - n-й элемент массива
От: MaximE Великобритания  
Дата: 28.04.03 14:24
Оценка: 8 (3)
Здравствуйте, Михаил Можаев, Вы писали:

А>>а по STL. Неужели там не реализована такая элементарная функциональнось???

А>>Если нет то хотелось бы спросить знатоков STL как же ее реализовать
А>>по правилам того самого STL?

ММ>Есть вариант — 2 map'а. Один — <string, int>, второй — <int, string>

ММ>Правда, заполнять дольше. Но заполнение делается один раз, так что ради скорости работы можно пойти на это.

Имхо, в данном случае, map + идексный vector будет побыстрее:

typedef map<string, int> THE_MAP;
typedef vector<THE_MAP::iterator> THE_VECTOR;

THE_MAP m;
THE_VECTOR v;

void Insert(string key, int value)
{
    v.push_back(m.insert(THE_MAP::value_type(key, value)).first);
}

int& Find(size_t index)
{
    return &v.at(index)->second;
}
Re[9]: std::map - n-й элемент массива
От: Дмитрий Наумов  
Дата: 28.04.03 14:53
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>Имхо, в данном случае, map + идексный vector будет побыстрее:


ME>
ME>typedef map<string, int> THE_MAP;
ME>typedef vector<THE_MAP::iterator> THE_VECTOR;

ME>THE_MAP m;
ME>THE_VECTOR v;

ME>void Insert(string key, int value)
ME>{
ME>    v.push_back(m.insert(THE_MAP::value_type(key, value)).first);
ME>}

ME>int& Find(size_t index)
ME>{
ME>    return &v.at(index)->second;
ME>}
ME>


Имхо, вариант ВЕКТОР СТРУКТУР лучше всего подходит идеалогически. Если у КАЖДОЙ строки в ListBox'е может быть ассоциирован cookie(он же user data) то чего извращаться? Объединить их идеалогически в одну сущность... А насчет мапа — человек собирается делать operator[] (в том или ином виде, но по сути это он) — имеем O(n) плюс добавление 10 элементов в мап (пусть и единожды) это не тоже самое что vector::reserve и 10 push_back'ов. Короче, пока не вижу зачем извращаться и придумывать себе геммор...
... << RSDN@Home 1.0 beta 6a >>
Re[9]: std::map - n-й элемент массива
От: Михаил Можаев Россия www.mozhay.chat.ru
Дата: 28.04.03 14:57
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>Имхо, в данном случае, map + идексный vector будет побыстрее:


Да, конечно. Я как-то и не придал значения, что второй элемент в паре — int. Для более сложных вариантов — 2 map'а было бы оправдано. А так — map + vector в самый раз.
... << RSDN@Home 1.0 beta 6a >>
Re[10]: std::map - n-й элемент массива
От: MaximE Великобритания  
Дата: 28.04.03 14:59
Оценка:
Здравствуйте, Дмитрий Наумов, Вы писали:

ДН>Имхо, вариант ВЕКТОР СТРУКТУР лучше всего подходит идеалогически. Если у КАЖДОЙ строки в ListBox'е может быть ассоциирован cookie(он же user data) то чего извращаться? Объединить их идеалогически в одну сущность... А насчет мапа — человек собирается делать operator[] (в том или ином виде, но по сути это он) — имеем O(n) плюс добавление 10 элементов в мап (пусть и единожды) это не тоже самое что vector::reserve и 10 push_back'ов. Короче, пока не вижу зачем извращаться и придумывать себе геммор...


Почти согласен, но про O(n) поподробнее.
Re[11]: std::map - n-й элемент массива
От: Дмитрий Наумов  
Дата: 28.04.03 15:05
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>Почти согласен, но про O(n) поподробнее.


Может я криво выразился?... Человеку нужен доступ к элементу мапа по индексу, оно же operator[], как он его сделает? std::advance, ну или for(...) для особых извращенцев. Ну вот его то сложность и будет O(n), а с вектором имеем O(1)
... << RSDN@Home 1.0 beta 6a >>
Re[10]: std::map - n-й элемент массива
От: MaximE Великобритания  
Дата: 28.04.03 15:06
Оценка:
Здравствуйте, Михаил Можаев, Вы писали:

ММ>Здравствуйте, MaximE, Вы писали:


ME>>Имхо, в данном случае, map + идексный vector будет побыстрее:


ММ>Да, конечно. Я как-то и не придал значения, что второй элемент в паре — int. Для более сложных вариантов — 2 map'а было бы оправдано. А так — map + vector в самый раз.


Я имел в виду, что в ComboBox'е каждый элемент имеет индекс. Этот индекс является индексом вектора ссылок на данные этого элемента.
Re[11]: std::map - n-й элемент массива
От: MaximE Великобритания  
Дата: 28.04.03 15:10
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>Здравствуйте, Дмитрий Наумов, Вы писали:


ДН>>Имхо, вариант ВЕКТОР СТРУКТУР лучше всего подходит идеалогически. Если у КАЖДОЙ строки в ListBox'е может быть ассоциирован cookie(он же user data) то чего извращаться? Объединить их идеалогически в одну сущность... А насчет мапа — человек собирается делать operator[] (в том или ином виде, но по сути это он) — имеем O(n) плюс добавление 10 элементов в мап (пусть и единожды) это не тоже самое что vector::reserve и 10 push_back'ов. Короче, пока не вижу зачем извращаться и придумывать себе геммор...


ME>Почти согласен, но про O(n) поподробнее.


Осталось выяснить у автора зачем ему именно map.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.