map и сортировка по значению
От: ss_sa  
Дата: 14.09.07 14:18
Оценка:
Есть 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 — это ассоциативный контейнер и для таких целей не предназначен.
Re: map и сортировка по значению
От: Bell Россия  
Дата: 14.09.07 14:30
Оценка:
Здравствуйте, ss_sa, Вы писали:

_>Есть std::map <string, vector>

_>Нужно рассортировать этот map не по string а по значению vector.size()
_>Как это сделать?

Завести вротой
map<size_t, vector*>
Любите книгу — источник знаний (с) М.Горький
Re: map и сортировка по значению
От: Sni4ok  
Дата: 14.09.07 14:32
Оценка:
Здравствуйте, ss_sa, Вы писали:

_>Есть std::map <string, vector>

_>Нужно рассортировать этот map не по string а по значению vector.size()

если эта std::map не жёстко прописана в интерфейсе, то имеет смысл заменить её на boost::multi_index_container
Re: map и сортировка по значению
От: jazzer Россия Skype: enerjazzer
Дата: 14.09.07 14:38
Оценка: 3 (1)
Здравствуйте, ss_sa, Вы писали:

_>Есть std::map <string, vector>

_>Нужно рассортировать этот map не по string а по значению vector.size()
_>Как это сделать?

Boost.Bimap
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

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 совсем неактуален.
Re: map и сортировка по значению
От: sc Россия  
Дата: 14.09.07 14:52
Оценка:
Здравствуйте, ss_sa, Вы писали:

_>Есть std::map <string, vector>

_>Нужно рассортировать этот map не по string а по значению vector.size()
_>Как это сделать?
можно перефразировать задачу и написать так:
#include <map>
#include <string>
#include <vector>

//typedef std::pair<std::string, std::vector<int> > Pair;
typedef std::map<int, std::pair<std::string, std::vector<int> > >str2vec;

int main()
{
  str2vec m;
  std::vector<int> v;
  v.push_back(1);
  m.insert(std::make_pair(v.size(), std::make_pair("abc", v)));
  return 0;
}
Re[2]: map и сортировка по значению
От: ss_sa  
Дата: 15.09.07 07:04
Оценка: :)
Здравствуйте, sc, Вы писали:

sc>можно перефразировать задачу и написать так:

sc>
sc>#include <map>
sc>#include <string>
sc>#include <vector>

sc>//typedef std::pair<std::string, std::vector<int> > Pair;
sc>typedef std::map<int, std::pair<std::string, std::vector<int> > >str2vec;

sc>int main()
sc>{
sc>  str2vec m;
sc>  std::vector<int> v;
sc>  v.push_back(1);
sc>  m.insert(std::make_pair(v.size(), std::make_pair("abc", v)));
sc>  return 0;
sc>}
sc>


Мда я в шоке. В кои веки решил изучить сегодняшний С++ по Страуструпу, а то вообще отстал от жизни, ну и заодно и что-то полезное написать, а тут опять те же грабли — если копнуть глубже то стандартная библиотека малопригодна для более менее сложных приложений. И стоило отменять указатель void*, вводить namespaces и вообще уродовать С, все равно ведь ручками придется писать. И чем тогда С++ лучше С?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[3]: map и сортировка по значению
От: Odi$$ey Россия http://malgarr.blogspot.com/
Дата: 15.09.07 07:34
Оценка:
Здравствуйте, ss_sa, Вы писали:

_>Мда я в шоке. В кои веки решил изучить сегодняшний С++ по Страуструпу,


ну так изучи для начала что такое map, для чего он предназначен а для чего — нет
... << RSDN@Home 1.2.0 alpha rev. 743>>
Re[3]: map и сортировка по значению
От: Аноним  
Дата: 15.09.07 08:11
Оценка:
_>Мда я в шоке. В кои веки решил изучить сегодняшний С++ по Страуструпу, а то вообще отстал от жизни, ну и заодно и что-то полезное написать, а тут опять те же грабли — если копнуть глубже то стандартная библиотека малопригодна для более менее сложных приложений. И стоило отменять указатель void*, вводить namespaces и вообще уродовать С, все равно ведь ручками придется писать. И чем тогда С++ лучше С?

ээээээ не прогай святое
Re[3]: map и сортировка по значению
От: Анатолий Широков СССР  
Дата: 15.09.07 08:17
Оценка:
_>Мда я в шоке. В кои веки решил изучить сегодняшний С++ по Страуструпу, а то вообще отстал от жизни, ну и заодно и что-то полезное написать, а тут опять те же грабли — если копнуть глубже то стандартная библиотека малопригодна для более менее сложных приложений. И стоило отменять указатель void*, вводить namespaces и вообще уродовать С, все равно ведь ручками придется писать. И чем тогда С++ лучше С?

Ты написал полную ерунду. Чем больше ты будешь узнавать о современном С++, тем более ты будешь это осознавать.
Re[4]: map и сортировка по значению
От: ss_sa  
Дата: 15.09.07 08:50
Оценка:
Здравствуйте, Odi$$ey, Вы писали:

_>>Мда я в шоке. В кои веки решил изучить сегодняшний С++ по Страуструпу,


OE>ну так изучи для начала что такое map, для чего он предназначен а для чего — нет


Там написано что это контейнер, типа vector и других. Нет а правда нельзя подшаманить раз C++ такой гибкий язык как все говорят, ну там сделать свой класс-потомок или еще как?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[5]: map и сортировка по значению
От: Анатолий Широков СССР  
Дата: 15.09.07 09:17
Оценка:
Здравствуйте, ss_sa, Вы писали:

_>Здравствуйте, Odi$$ey, Вы писали:


_>>>Мда я в шоке. В кои веки решил изучить сегодняшний С++ по Страуструпу,


OE>>ну так изучи для начала что такое map, для чего он предназначен а для чего — нет


_>Там написано что это контейнер, типа vector и других. Нет а правда нельзя подшаманить раз C++ такой гибкий язык как все говорят, ну там сделать свой класс-потомок или еще как?


Для начала надо определиться с постановкой задачи. Можно на словах услышать что ты хочешь сделать?
Re[3]: map и сортировка по значению
От: sc Россия  
Дата: 15.09.07 10:14
Оценка:
Здравствуйте, ss_sa, Вы писали:

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


sc>>можно перефразировать задачу и написать так:

sc>>
sc>>#include <map>
sc>>#include <string>
sc>>#include <vector>

sc>>//typedef std::pair<std::string, std::vector<int> > Pair;
sc>>typedef std::map<int, std::pair<std::string, std::vector<int> > >str2vec;

sc>>int main()
sc>>{
sc>>  str2vec m;
sc>>  std::vector<int> v;
sc>>  v.push_back(1);
sc>>  m.insert(std::make_pair(v.size(), std::make_pair("abc", v)));
sc>>  return 0;
sc>>}
sc>>


_>Мда я в шоке.

Я тоже. С утра на трезвую голову Не смог вечером удержать полет фантазии
_>skipped
Выше предлагалось использовать map для хранения указателей, но лучше использовать multimap, так как могут встретиться одинаковые длины. Вот что-то более-менее похожее на правду.
#include <map>
#include <vector>
#include <string>
#include <iostream>
#include <algorithm>

typedef std::vector<int> intvec;
typedef std::map<std::string, intvec> str2ivec;
typedef std::multimap<size_t, intvec*> size2ivec;
typedef std::pair<str2ivec::iterator, bool> it2bool;

void printmm(std::pair<size_t, intvec*> const& p)
{
    std::cout << p.first << "\t\t"; 
    std::copy(p.second->begin(), p.second->end(), std::ostream_iterator<int>(std::cout, " "));
    std::cout << std::endl;
}

it2bool insert(std::string const &p1, intvec const &p2, 
               str2ivec &m, size2ivec &mm)
{
    it2bool it = m.insert(std::make_pair(p1, p2));
    if(it.second)
    {        
        mm.insert(std::make_pair(p2.size(), &it.first->second));
    }
    return it;
}

int main(int argc, char* argv[])
{    
    intvec        v;
    v.push_back(10);
    str2ivec    m;
    size2ivec    mm;

    insert(std::string("abc"), v, m, mm);
    if(!insert(std::string("abc"), v, m, mm).second)
        std::cout << "abc key is already in map" << std::endl;
    v.push_back(20);
    insert(std::string("def"), v, m, mm);

    std::cout << "length\t\tvalues" << std::endl;
    std::for_each(mm.begin(), mm.end(), printmm);
    return 0;
}

Печатает:
abc key is already in map
length values
1 10
2 10 20
Re[5]: map и сортировка по значению
От: sc Россия  
Дата: 15.09.07 10:30
Оценка:
Здравствуйте, ss_sa, Вы писали:

_>Здравствуйте, Odi$$ey, Вы писали:


_>>>Мда я в шоке. В кои веки решил изучить сегодняшний С++ по Страуструпу,


OE>>ну так изучи для начала что такое map, для чего он предназначен а для чего — нет


_>Там написано что это контейнер, типа vector и других. Нет а правда нельзя подшаманить раз C++ такой гибкий язык как все говорят, ну там сделать свой класс-потомок или еще как?


Типа vector, но не такой. Есть три вида контейнеров: с произвольным доступом, с последовательным и ассоциативные. map — ассоциативный. Сделан чаще на двоичном дереве (ч/б). Следовательно его нельзя сортировать, так как он и так упорядочен, согласно какому-то ключу. Т.е. одно дерево — один ключ. В даннай задаче нужно сортировать по двум ключам, значит map не подходит. Как обходное решение, можно использовать несколько контейнеров. Основной и дополнительные, с указателями (а лучше итераторами) на элементы в основном, и разными порядками сортировки. Помнить о валидности указателей/итераторов.
Re[6]: map и сортировка по значению
От: ss_sa  
Дата: 15.09.07 13:18
Оценка:
Здравствуйте, Анатолий Широков, Вы писали:

OE>>>ну так изучи для начала что такое map, для чего он предназначен а для чего — нет


_>>Там написано что это контейнер, типа vector и других. Нет а правда нельзя подшаманить раз C++ такой гибкий язык как все говорят, ну там сделать свой класс-потомок или еще как?


АШ>Для начала надо определиться с постановкой задачи. Можно на словах услышать что ты хочешь сделать?


Да вообщем-то так учебная задача, есть web лог, нужно
1. подсчитать все страницы
2. вывести на каждую страницу статистику те сколько раз посещали, ip, браузера, и ид
Охото сделать все на С++, по последним достижениям техники а то чувствую отстал от жизни.

В принцепе все получилось, но вот отсортировать полученый массив по количеству посещений почему-то не удалось
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[6]: map и сортировка по значению
От: ss_sa  
Дата: 15.09.07 13:18
Оценка:
Здравствуйте, sc, Вы писали:

_>>Там написано что это контейнер, типа vector и других. Нет а правда нельзя подшаманить раз C++ такой гибкий язык как все говорят, ну там сделать свой класс-потомок или еще как?


sc>Типа vector, но не такой. Есть три вида контейнеров: с произвольным доступом, с последовательным и ассоциативные. map — ассоциативный.


Вообщем они все имеют доступ еще и по итератору.

sc>В даннай задаче нужно сортировать по двум ключам, значит map не подходит. Как обходное решение, можно использовать несколько контейнеров. Основной и дополнительные, с указателями (а лучше итераторами) на элементы в основном, и разными порядками сортировки. Помнить о валидности указателей/итераторов.


Спасибо я понял что без другого map не обойтись.

зы Нет ну надо же оказывается С++ опять надо учить раньше сидел на старом диалекте BCC и спокойно клепал програмки, а оказывается жизнь ушла вперед и С++ это теперь совсем другой язык который был 8 лет назад.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[4]: map и сортировка по значению
От: ss_sa  
Дата: 15.09.07 13:18
Оценка:
Здравствуйте, sc, Вы писали:

sc>Выше предлагалось использовать map для хранения указателей, но лучше использовать multimap, так как могут встретиться одинаковые длины. Вот что-то более-менее похожее на правду.

да multimap лучше.

sc>
sc>#include <map>
sc>#include <vector>
sc>#include <string>
sc>#include <iostream>
sc>#include <algorithm>

sc>typedef std::vector<int> intvec;
sc>typedef std::map<std::string, intvec> str2ivec;
sc>typedef std::multimap<size_t, intvec*> size2ivec;
sc>typedef std::pair<str2ivec::iterator, bool> it2bool;

sc>void printmm(std::pair<size_t, intvec*> const& p)
sc>{
sc>    std::cout << p.first << "\t\t"; 
sc>    std::copy(p.second->begin(), p.second->end(), std::ostream_iterator<int>(std::cout, " "));
sc>    std::cout << std::endl;
sc>}

sc>it2bool insert(std::string const &p1, intvec const &p2, 
sc>               str2ivec &m, size2ivec &mm)
sc>{
sc>    it2bool it = m.insert(std::make_pair(p1, p2));
sc>    if(it.second)
sc>    {        
sc>        mm.insert(std::make_pair(p2.size(), &it.first->second));
sc>    }
sc>    return it;
sc>}

sc>int main(int argc, char* argv[])
sc>{    
sc>    intvec        v;
sc>    v.push_back(10);
sc>    str2ivec    m;
sc>    size2ivec    mm;

sc>    insert(std::string("abc"), v, m, mm);
sc>    if(!insert(std::string("abc"), v, m, mm).second)
sc>        std::cout << "abc key is already in map" << std::endl;
sc>    v.push_back(20);
sc>    insert(std::string("def"), v, m, mm);

sc>    std::cout << "length\t\tvalues" << std::endl;
sc>    std::for_each(mm.begin(), mm.end(), printmm);
sc>    return 0;
sc>}

sc>Печатает:
sc>abc key is already in map
sc>length values
sc>1 10
sc>2 10 20

Спасибо, но право не стоило, уж лучше самому потихоньку разбираться.
А что правда templates наследование не поддерживают?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[5]: map и сортировка по значению
От: sc Россия  
Дата: 15.09.07 14:15
Оценка:
Здравствуйте, ss_sa, Вы писали:

<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. Определить копиктор и =. В общем следить за валидностью указателей/итераторов.
Re[7]: map и сортировка по значению
От: Анатолий Широков СССР  
Дата: 15.09.07 16:46
Оценка:
Здравствуйте, 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;
}
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.