Russian Qt Forum

Qt => Общие вопросы => Тема начата: Fat-Zer от Февраль 26, 2011, 21:25



Название: контейнер один к одному
Отправлено: Fat-Zer от Февраль 26, 2011, 21:25
есть какой-нить готовый контейнер реализующий связь один к одному? что-то вроде QMap, только с быстрым поиском по значению и контролирующий единственность как ключа, так и значения.

На чём такой разумно было бы реализовывать?


Название: Re: контейнер один к одному
Отправлено: brankovic от Февраль 26, 2011, 22:10
boost::bimap


Название: Re: контейнер один к одному
Отправлено: fuCtor от Февраль 26, 2011, 22:16
А чем QMap не подходит?
Цитировать
iterator QMap::insert ( const Key & key, const T & value )

Inserts a new item with the key key and a value of value.

If there is already an item with the key key, that item's value is replaced with value.

If there are multiple items with the key key, the most recently inserted item's value is replaced with value.

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

Остается лишь вопрос скорости.


Название: Re: контейнер один к одному
Отправлено: Fat-Zer от Февраль 26, 2011, 22:44
boost::bimap
спасибо... с бустом пока не знаком, но давно хотел поковырять...

А чем QMap не подходит?
вы не поверите... тем что надо ручками проверять и скоростью :D


Название: Re: контейнер один к одному
Отправлено: Igors от Февраль 26, 2011, 22:54
Хмм... А Вы можете пояснить как так: если нельзя вставить 1 ключ дважды,
Цитировать
If there is already an item with the key key, that item's value is replaced with value.
То откуда же возьмутся "multiple items with the key key" о которых говорится дальше ? 
Цитировать
If there are multiple items with the key key, the most recently inserted item's value is replaced with value.
:)

вы не поверите... тем что надо ручками проверять и скоростью :D
Ну вероятно fuCtor имел ввиду 2 QMap (обратные ключ-значение). Это сделать несложно, но может получиться "жирно" (расходно) по ключам.

Кстати давно хотел посмотреть хорошую реализацию ключа-указателя... так что welcome


Название: Re: контейнер один к одному
Отправлено: Fat-Zer от Февраль 26, 2011, 23:04
Хмм... А Вы можете пояснить как так: если нельзя вставить 1 ключ дважды,
Цитировать
If there is already an item with the key key, that item's value is replaced with value.
То откуда же возьмутся "multiple items with the key key" о которых говорится дальше ? 
Цитировать
If there are multiple items with the key key, the most recently inserted item's value is replaced with value.
:)
следующая строчка в асистенте:
Цитировать
iterator QMap::insertMulti ( const Key & key, const T & value )
Inserts a new item with the key key and a value of value.

If there is already an item with the same key in the map, this function will simply create a new one. (This behavior is different from insert(), which overwrites the value of an existing item.)

Ну вероятно fuCtor имел ввиду 2 QMap (обратные ключ-значение). Это сделать несложно, но может получиться "жирно" (расходно) по ключам.

Кстати давно хотел посмотреть хорошую реализацию ключа-указателя... так что welcome
или так или каждый раз при добавление смотреть, нет ли элемента с таким значением в map'e. а при запросе - искать по значению.


Название: Re: контейнер один к одному
Отправлено: Karl-Philipp от Февраль 27, 2011, 12:01
Fat-zer, а смотрел ли на QHash? Если да, то чем он не соответствует требованиям, указанным в первом твоем посте?


Название: Re: контейнер один к одному
Отправлено: Fat-Zer от Февраль 27, 2011, 12:40
Fat-zer, а смотрел ли на QHash? Если да, то чем он не соответствует требованиям, указанным в первом твоем посте?
Так это же теже яица, что и QMap только через Хеш-таблицу. Притензии к нему теже.


Название: Re: контейнер один к одному
Отправлено: Karl-Philipp от Февраль 27, 2011, 12:49
Fat-zer, а смотрел ли на QHash? Если да, то чем он не соответствует требованиям, указанным в первом твоем посте?
Так это же теже яица, что и QMap только через Хеш-таблицу. Притензии к нему теже.
Я, наверное, неправильно понял тебя, но в Assistant'e про QHash написано:
Цитировать
It stores (key, value) pairs and provides very fast lookup of the value associated with a key.
+
Цитировать
QHash provides faster lookups than QMap. (See Algorithmic Complexity for details.)


Название: Re: контейнер один к одному
Отправлено: Fat-Zer от Февраль 27, 2011, 12:55
ты, наверное, не правильно понял асистент. он быстро ищет значение по ключу, а обратный поиск(QHash::key()) занимает много времени.


Название: Re: контейнер один к одному
Отправлено: Karl-Philipp от Февраль 27, 2011, 13:20
наверное)


Название: Re: контейнер один к одному
Отправлено: fuCtor от Февраль 27, 2011, 15:55
Пропустил пункт про уникальность и значения, тогда можно попробовать сделать финт ушами:
Своя структура, с перегруженным оператором сравнения: только использовать не полное совпадение обоих значений, а частичное. Тогда если если добавлять элемент AB а потом AC, то должен сказать что такое уже есть, и наоборот DC так же выдаст совпадение, а DE без проблем добавиться.
Поиск по ключу производится путем поиска структуры с пустым значением, для значения соответственно наоборот. Тогда может даже можно использовать и QSet.

Работоспособность подхода не проверял и как отразится на скорости пока не особо понятно.


Название: Re: контейнер один к одному
Отправлено: Igors от Февраль 27, 2011, 16:20
Пропустил пункт про уникальность и значения, тогда можно попробовать сделать финт ушами:
Своя структура, с перегруженным оператором сравнения: только использовать не полное совпадение обоих значений, а частичное. Тогда если если добавлять элемент AB а потом AC, то должен сказать что такое уже есть, и наоборот DC так же выдаст совпадение, а DE без проблем добавиться.
Поиск по ключу производится путем поиска структуры с пустым значением, для значения соответственно наоборот. Тогда может даже можно использовать и QSet.

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

Код
C++ (Qt)
struct CDataKey1 {
bool operator == ( const CDataKey1 & sec ) const;  // сравнивает по 1-му ключу
bool operator < ( const CDataKey1 & sec ) const;  // сравнивает по 1-му ключу
 
const MyClass * mData;
};
 
struct CDataKey2 {
bool operator == ( const CDataKey2 & sec ) const;  // сравнивает по 2-му ключу
bool operator < ( const CDataKey2 & sec ) const;  // сравнивает по 2-му ключу
 
const MyClass * mData;
};
 
Ну и те же 2 QSet - и все дела


Название: Re: контейнер один к одному
Отправлено: fuCtor от Февраль 27, 2011, 16:46
Суть таже, только у меня один контейнер получался. Это уже кому как удобней.


Название: Re: контейнер один к одному
Отправлено: Fat-Zer от Февраль 27, 2011, 17:07
fuCtor, не сработает... QSet'у нужна функция qHash() и на неё накладывается требование:
a==b => qHash(a)==qHash(b)
для AB==AC такое придупать не получится...
Igors, это может и сработает... в любом случае реализация на двух хеш-таблицах должна работать. Только надо будет причесать.

ЗЫ: Моя подзадача, это применение перестановки в прямом и обратном направлении.


Название: Re: контейнер один к одному
Отправлено: brankovic от Февраль 28, 2011, 10:56
ЗЫ: Моя подзадача, это применение перестановки в прямом и обратном направлении.

зачем вообще тогда мэпы, нельзя просто хранить вектор индексов и по нему делать перестановку?