Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > сортировка ключей мультимапа


Автор: kuvshinka 22.11.2012, 19:20
Код

   QMultiMap <ushort, void*> mmap;
    mmap.insert(94, NULL);
    mmap.insert(82, NULL);
    mmap.insert(8, NULL);
    mmap.insert(150, NULL);
   qDebug() << mmap.keys();


в итоговом листе мапа ключи автоматически отсортируются по возрастанию их значений...а как их не сортировать? то есть чтобы данные легли в лист мапа точно в порядке их записи в этот мап (нулевой элемент списка мапа=94, 2-ой=82 и т.д.)...если в мапе нельзя отключить сортировку данных, то подскажите другой контейнер для хранения данных, но жел-но в таком же виде - типа "<ключ, данные>"... пробовала QHash, но в него вообще непонятно как данные заносятся - и не сортируются, и не в порядке их записи...

Автор: Snake174 23.11.2012, 05:15
Попробуй использовать QVector<QPair<ushort, void*> > mmap;

Автор: kuvshinka 23.11.2012, 05:25
понятно...попробую...то есть у мультимапа вообще никак нельзя отключить автосортировку ключей?

Автор: Jeka178RUS 23.11.2012, 08:35
Цитата(kuvshinka @ 23.11.2012,  05:25)
понятно...попробую...то есть у мультимапа вообще никак нельзя отключить автосортировку ключей?

Из доки:

QMap and QHash provide very similar functionality. The differences are:
QHash provides faster lookups than QMap. (See Algorithmic Complexity for details.)
When iterating over a QHash, the items are arbitrarily ordered. With QMap, the items are always sorted by key.
The key type of a QHash must provide operator==() and a global qHash(Key) function. The key type of a QMap must provide operator<() specifying a total order.

Так что если важен порядок элементов, а не быстрый доступ по ключу, тогда вам необходимо использовать контейнеры QList или QVector. Тут уж как удобнее контейнер пар элементов или два контейнера, но доступ к элементам будет линейным. Ну или можно хранить отдельно QMap и Vector ключей в нужном вам порядке, если памяти не жалко

Автор: kuvshinka 23.11.2012, 20:08
Код

 QVector <QPair<ushort, void*> > vec;
    vec.append(qMakePair((ushort)71,  (void*)NULL));
    vec.append(qMakePair((ushort)63,  (void*)NULL));
    vec.append(qMakePair((ushort)26,  (void*)NULL));
    vec.append(qMakePair((ushort)110, (void*)NULL));

подскажите пож-та правильный синтаксис команд indexof и contains:
Код

if  (vec.contains( QPair <(ushort)26, (void*)NULL>  )) - неверно 
qDebug() << vec.indexOf( QPair <((ushort)26, (void*)NULL)>  , 0); - неверно 



Код

    QMultiHash <ushort, void *> hh;
    hh.insert(71,  NULL);
    hh.insert(886, NULL);
    hh.insert(5,   NULL);
    hh.insert(99,  NULL);
    qDebug() << hh.keys();

ответ: (886, 71, 5, 99) 
так по какому же принципу (в каком порядке) записываются данные в QMultiHash? 

Автор: volatile 23.11.2012, 23:52
Цитата(kuvshinka @  23.11.2012,  20:08 Найти цитируемый пост)
так по какому же принципу (в каком порядке) записываются данные в QMultiHash? 

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

Автор: borisbn 24.11.2012, 11:34
Цитата(kuvshinka @  23.11.2012,  20:08 Найти цитируемый пост)
if  (vec.contains( QPair <(ushort)26, (void*)NULL>  )) - неверно 
qDebug() << vec.indexOf( QPair <((ushort)26, (void*)NULL)>  , 0); - неверно 

конечно неверно...
Код
qDebug() << vec.indexOf( qMakePair( (ushort)26, (void*)NULL ), 0 );

я бы посоветовал пользоваться stl-алгоритмами, т.к. в них можно задать предикат поиска. типа такого
Код

template< class PairType >
struct PairEqualByFirst {
    EqualByFirst( const PairType::first_type & f ) : m_first( f ) {}
    bool operator()( const QPair< PairType::first_type, PairType::second_type > & p ) {
        return p.first == m_first;
    }
private:
    PairType::first_type m_first;
};

typedef QVector <QPair<ushort, void*> > PairVector;
PairVector vec;
    vec.append(qMakePair((ushort)71,  (void*)NULL));
    vec.append(qMakePair((ushort)63,  (void*)NULL));
    vec.append(qMakePair((ushort)26,  (void*)NULL));
    vec.append(qMakePair((ushort)110, (void*)NULL));
PairVector::iterator = std::find_if( vec.begin(), vec.end(), PairEqualByFirst< PairVector::value_type >( 26 ) );

не проверял, но, возможно, где-то не хватает typename перед типом (привык, что студия поумнее гцц и не требует этого атавизма)

Автор: kuvshinka 24.11.2012, 21:34
понятно...и все-таки возвращаясь к мультимапу - а что тогда делает его фукнция setInsertInOrder? по названию вроде похоже на задание порядка записи данных в мап (мне бы как раз то что надо было бы)...почему-то описания этого метода нет...

Автор: kuvshinka 25.11.2012, 20:53
Jeka178RUS: а что будет быстрее работать - отдельно QMap с данными и Vector ключей к ним в нужном мне порядке ИЛИ вектор пары 
Код

QVector<QPair<ushort, void*> > mmap; 

Автор: Jeka178RUS 26.11.2012, 14:16
Цитата(kuvshinka @ 25.11.2012,  20:53)
Jeka178RUS: а что будет быстрее работать - отдельно QMap с данными и Vector ключей к ним в нужном мне порядке ИЛИ вектор пары 
Код

QVector<QPair<ushort, void*> > mmap; 


Смотря в том какой доступ для вас нужен:
1) Вас интересует доступ по ключу (или эта операция используется значительно чаще остальных), тогда вы используете QHash для доступа к элементам за константное время и поиск позиции ключа в массиве ключей за линейное время.

2) Порядок элементов первостепенен, тогда выборка из вектора по индексу за константное время, но поиск по ключу за линейное время. Тогда вектор пар удобнее, доступ к элементу пары всегда постоянен.

Хранение отдельно по мне удобнее и имеет одно преимущество:
при необходимости доступа по ключу, вы обращаетесь к Hash - константное время, а по индексу вы обращаетесь в вектору за ключом (константное), а по этому ключу к хешу (опять константное время), а операция получения индекса ключа в векторе остается линейной.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)