Есть std::map <string, vector>
Нужно рассортировать этот map не по string а по значению vector.size()
Как это сделать?
Re: map и сортировка по значению
От:
Аноним
Дата:
14.09.07 14:28
Оценка:
Здравствуйте, ss_sa, Вы писали:
_>Есть std::map <string, vector> _>Нужно рассортировать этот map не по string а по значению vector.size() _>Как это сделать?
Завести дополнительную структуру данных.
map — это ассоциативный контейнер и для таких целей не предназначен.
Здравствуйте, ss_sa, Вы писали:
_>Есть std::map <string, vector> _>Нужно рассортировать этот map не по string а по значению vector.size() _>Как это сделать?
Здравствуйте, ss_sa, Вы писали:
_>Есть std::map <string, vector> _>Нужно рассортировать этот map не по string а по значению vector.size() _>Как это сделать?
You will always get what you always got
If you always do what you always did
Re[2]: map и сортировка по значению
От:
Аноним
Дата:
14.09.07 14:42
Оценка:
Здравствуйте, Bell, Вы писали:
B>Здравствуйте, ss_sa, Вы писали:
_>>Есть std::map <string, vector> _>>Нужно рассортировать этот map не по string а по значению vector.size() _>>Как это сделать?
B>Завести вротой B>
B>map<size_t, vector*>
B>
Тогда уж лучше банальный vector< vector* > и сортировать его по мере необходимости.
А иначе если ты какой из векторов изменишь, то будет твой map совсем неактуален.
Здравствуйте, ss_sa, Вы писали:
_>Есть std::map <string, vector> _>Нужно рассортировать этот map не по string а по значению vector.size() _>Как это сделать?
можно перефразировать задачу и написать так:
Мда я в шоке. В кои веки решил изучить сегодняшний С++ по Страуструпу, а то вообще отстал от жизни, ну и заодно и что-то полезное написать, а тут опять те же грабли — если копнуть глубже то стандартная библиотека малопригодна для более менее сложных приложений. И стоило отменять указатель void*, вводить namespaces и вообще уродовать С, все равно ведь ручками придется писать. И чем тогда С++ лучше С?
Здравствуйте, ss_sa, Вы писали:
_>Мда я в шоке. В кои веки решил изучить сегодняшний С++ по Страуструпу,
ну так изучи для начала что такое map, для чего он предназначен а для чего — нет
... << RSDN@Home 1.2.0 alpha rev. 743>>
Re[3]: map и сортировка по значению
От:
Аноним
Дата:
15.09.07 08:11
Оценка:
_>Мда я в шоке. В кои веки решил изучить сегодняшний С++ по Страуструпу, а то вообще отстал от жизни, ну и заодно и что-то полезное написать, а тут опять те же грабли — если копнуть глубже то стандартная библиотека малопригодна для более менее сложных приложений. И стоило отменять указатель void*, вводить namespaces и вообще уродовать С, все равно ведь ручками придется писать. И чем тогда С++ лучше С?
_>Мда я в шоке. В кои веки решил изучить сегодняшний С++ по Страуструпу, а то вообще отстал от жизни, ну и заодно и что-то полезное написать, а тут опять те же грабли — если копнуть глубже то стандартная библиотека малопригодна для более менее сложных приложений. И стоило отменять указатель void*, вводить namespaces и вообще уродовать С, все равно ведь ручками придется писать. И чем тогда С++ лучше С?
Ты написал полную ерунду. Чем больше ты будешь узнавать о современном С++, тем более ты будешь это осознавать.
Здравствуйте, Odi$$ey, Вы писали:
_>>Мда я в шоке. В кои веки решил изучить сегодняшний С++ по Страуструпу,
OE>ну так изучи для начала что такое map, для чего он предназначен а для чего — нет
Там написано что это контейнер, типа vector и других. Нет а правда нельзя подшаманить раз C++ такой гибкий язык как все говорят, ну там сделать свой класс-потомок или еще как?
Здравствуйте, ss_sa, Вы писали:
_>Здравствуйте, Odi$$ey, Вы писали:
_>>>Мда я в шоке. В кои веки решил изучить сегодняшний С++ по Страуструпу,
OE>>ну так изучи для начала что такое map, для чего он предназначен а для чего — нет
_>Там написано что это контейнер, типа vector и других. Нет а правда нельзя подшаманить раз C++ такой гибкий язык как все говорят, ну там сделать свой класс-потомок или еще как?
Для начала надо определиться с постановкой задачи. Можно на словах услышать что ты хочешь сделать?
_>Мда я в шоке.
Я тоже. С утра на трезвую голову Не смог вечером удержать полет фантазии _>skipped
Выше предлагалось использовать map для хранения указателей, но лучше использовать multimap, так как могут встретиться одинаковые длины. Вот что-то более-менее похожее на правду.
Здравствуйте, ss_sa, Вы писали:
_>Здравствуйте, Odi$$ey, Вы писали:
_>>>Мда я в шоке. В кои веки решил изучить сегодняшний С++ по Страуструпу,
OE>>ну так изучи для начала что такое map, для чего он предназначен а для чего — нет
_>Там написано что это контейнер, типа vector и других. Нет а правда нельзя подшаманить раз C++ такой гибкий язык как все говорят, ну там сделать свой класс-потомок или еще как?
Типа vector, но не такой. Есть три вида контейнеров: с произвольным доступом, с последовательным и ассоциативные. map — ассоциативный. Сделан чаще на двоичном дереве (ч/б). Следовательно его нельзя сортировать, так как он и так упорядочен, согласно какому-то ключу. Т.е. одно дерево — один ключ. В даннай задаче нужно сортировать по двум ключам, значит map не подходит. Как обходное решение, можно использовать несколько контейнеров. Основной и дополнительные, с указателями (а лучше итераторами) на элементы в основном, и разными порядками сортировки. Помнить о валидности указателей/итераторов.
Здравствуйте, Анатолий Широков, Вы писали:
OE>>>ну так изучи для начала что такое map, для чего он предназначен а для чего — нет
_>>Там написано что это контейнер, типа vector и других. Нет а правда нельзя подшаманить раз C++ такой гибкий язык как все говорят, ну там сделать свой класс-потомок или еще как?
АШ>Для начала надо определиться с постановкой задачи. Можно на словах услышать что ты хочешь сделать?
Да вообщем-то так учебная задача, есть web лог, нужно
1. подсчитать все страницы
2. вывести на каждую страницу статистику те сколько раз посещали, ip, браузера, и ид
Охото сделать все на С++, по последним достижениям техники а то чувствую отстал от жизни.
В принцепе все получилось, но вот отсортировать полученый массив по количеству посещений почему-то не удалось
Здравствуйте, sc, Вы писали:
_>>Там написано что это контейнер, типа vector и других. Нет а правда нельзя подшаманить раз C++ такой гибкий язык как все говорят, ну там сделать свой класс-потомок или еще как?
sc>Типа vector, но не такой. Есть три вида контейнеров: с произвольным доступом, с последовательным и ассоциативные. map — ассоциативный.
Вообщем они все имеют доступ еще и по итератору.
sc>В даннай задаче нужно сортировать по двум ключам, значит map не подходит. Как обходное решение, можно использовать несколько контейнеров. Основной и дополнительные, с указателями (а лучше итераторами) на элементы в основном, и разными порядками сортировки. Помнить о валидности указателей/итераторов.
Спасибо я понял что без другого map не обойтись.
зы Нет ну надо же оказывается С++ опять надо учить раньше сидел на старом диалекте BCC и спокойно клепал програмки, а оказывается жизнь ушла вперед и С++ это теперь совсем другой язык который был 8 лет назад.
Здравствуйте, sc, Вы писали:
sc>Выше предлагалось использовать map для хранения указателей, но лучше использовать multimap, так как могут встретиться одинаковые длины. Вот что-то более-менее похожее на правду.
да multimap лучше.
sc>
<skipped> _>А что правда templates наследование не поддерживают?
Почему же? Поддерживают.
template <
class Key,
class Type,
class Compare = std::less<Key>,
class Allocator = std::allocator<std::pair<const Key, Type> > >
class mmap: public std::map<Key, Type, Compare, Allocator>
{
};
Можно добавить вектор/map multimap'ов (как член mmap'а) и методы добавления/удаления/выбора сортировщиков. Определить методы добавления/удаления в/из mmap. Определить копиктор и =. В общем следить за валидностью указателей/итераторов.
Здравствуйте, ss_sa, Вы писали:
_>Здравствуйте, Анатолий Широков, Вы писали:
OE>>>>ну так изучи для начала что такое map, для чего он предназначен а для чего — нет
_>>>Там написано что это контейнер, типа vector и других. Нет а правда нельзя подшаманить раз C++ такой гибкий язык как все говорят, ну там сделать свой класс-потомок или еще как?
АШ>>Для начала надо определиться с постановкой задачи. Можно на словах услышать что ты хочешь сделать?
_>Да вообщем-то так учебная задача, есть web лог, нужно _>1. подсчитать все страницы _>2. вывести на каждую страницу статистику те сколько раз посещали, ip, браузера, и ид _>Охото сделать все на С++, по последним достижениям техники а то чувствую отстал от жизни.
Вот это совсем другое дело. Вот набросок, который можно расширить по желанию:
#include <iostream>
#include <string>
#include <sstream>
#include <map>
#include <algorithm>
// запись в логеstruct entry
{
std::string datetime;
std::string page;
std::string ip;
std::string browser;
friend std::istream& operator>>(std::istream &stream, entry &e)
{
entry t;
if( !(stream >> t.datetime) )
return stream;
if( !(stream >> t.page) )
return stream;
if( !(stream >> t.ip) )
return stream;
if( !(stream >> t.browser) )
return stream;
e = t;
return stream;
}
}; // struct entry..
// менеджер сбора статистикиclass statistic
{
private: // данные
// статистика посещения страниц
std::map<std::string, int> page_to_visit;
// информация о количестве визитов
std::multimap<int, std::string> visit_to_page;
public:
// запросить статистику по количеству визитов посещенных страницconst std::multimap<int, std::string>& get_page_by_visit() const
{
return visit_to_page;
}
// обработать запись лога
statistic& process(const entry &e)
{
// прочитали количество визитов данной страницы
// до регистрации новой записи логеint visit_count = page_to_visit[e.page]++;
if( visit_count ) {
// запросили диапазон соответствующий полученному
// количеству визитов
std::pair<
std::multimap<int, std::string>::iterator,
std::multimap<int, std::string>::iterator>
range = visit_to_page.equal_range(visit_count);
// ищем в нем нашу страницуfor(std::multimap<int, std::string>::iterator i = range.first; i != range.second; i++)
// если страница найденаif( i->second == e.page )
{
// удаляем старое упоминание поскольку число вхождений увеличилось
// и регистрируем запись с новым количеством
visit_to_page.insert(
visit_to_page.erase(i),
std::make_pair<int, std::string>(visit_count+1, e.page)
);
break;
}
} else {
// регистрируем первый раз
visit_to_page.insert(
std::make_pair<int, std::string>(visit_count+1, e.page)
);
}
return *this;
} // add..
}; // class statistic..
// вспомогательный функтор, который выполняет роль посредника
// между алгоритмом for_each и менеждером статистикиstruct process_entry
{
private:
statistic *mng;
public:
process_entry(statistic &mng) : mng(&mng) {}
void operator()(const entry &e)
{
mng->process(e);
}
}; // struct process_entry..
// вспомогательный класс для вывода пары в потокstruct visit_count_page
{
const std::pair<const int, std::string> *p;
visit_count_page(const std::pair<const int, std::string> &r) : p(&r) {}
friend std::ostream& operator<<(std::ostream &stream, const visit_count_page &p)
{
stream << p.p->first << " " << p.p->second;
return stream;
}
}; // struct visit_count_page..int main()
{
statistic mng;
std::istringstream stream(
"200709152019 index.html 127.0.0.1 IE7\n"
"200709152025 index.html 127.0.0.1 IE7\n"
"200709152125 index.html 127.0.0.1 IE7\n"
"200709152225 overview.html 127.0.0.1 IE7\n"
"200709152325 overview.html 127.0.0.1 IE7\n"
"200709152327 about.html 127.0.0.1 IE7\n"
);
std::for_each(
std::istream_iterator<entry>(stream),
std::istream_iterator<entry>(),
process_entry(mng)
);
const std::multimap<int, std::string> m = mng.get_page_by_visit();
// вывод статистики по количеству посещений в порядке убывания интереса
std::copy(
m.rbegin(),
m.rend(),
std::ostream_iterator<visit_count_page>(std::cout, "\n")
);
return 0;
}