Re[9]: Зачем существует std::multiset
От: igna Россия  
Дата: 17.06.08 05:30
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>std::vector — дефолтный контейнер, это использование других вместо него нужно обосновывать.


Хорошо, согласен.

AG>А если даже взять словарь, где пользователь добавляет слова, нужен mulitmap, а не multiset, потому что у слов есть значения.


А вот этот аргумент не понял. У слов есть значения? Можно и под этим углом посмотреть, но зачем? Например пользователь создает новую статью, и часть программы отвечающая за создание объекта Статья знает, что две части этого объекта будут храниться отдельно? Или она этого не знает, и созданный ей объект преобразуется затем к виду подходящему для хранения в multimap?
Re[7]: Зачем существует std::multiset
От: igna Россия  
Дата: 17.06.08 05:35
Оценка:
Здравствуйте, Erop, Вы писали:

E>1) Советую посмотреть, например, как работает скроллер в лингво.


Спасибо за совет, а на что обратить внимание?

E>2) Жизнь такова, что обычно словарей много, а пользователю надо показывать их слияние...


Можно поподробнее? Это аргумент за или против multiset?
Re[5]: Зачем существует std::multiset
От: maq Россия http://www.maqdev.com
Дата: 17.06.08 09:46
Оценка:
AG>Затем, чтобы значение ID можно было передать в eqaul_range.

В целом согласен, хотя это и не обязательно. В equal_range, или multiset:equal_range можно передать класс с инициализированным полем ID.
Re[8]: Зачем существует std::multiset
От: Erop Россия  
Дата: 17.06.08 10:06
Оценка:
Здравствуйте, igna, Вы писали:

I>Спасибо за совет, а на что обратить внимание?

Ну подёргай его, понажимай в разные места и посмотри куда попадаешь. Узнаешь много нового. Так же, кстати, и другие словари читят.
Например, популярная темя -- попадать по движению очень длинного скроллера не в любую точку, а в границу логического контекста.

E>>2) Жизнь такова, что обычно словарей много, а пользователю надо показывать их слияние...

I>Можно поподробнее? Это аргумент за или против multiset?
Ну не годятся стандартные контейнеры в электронных словарях. Так как тебе надо не вычитывая весь словарь с диска достать из него толкьо кусок, идущий подряд. При этом надо не из одного словаря, а из коллекции и всё это смёржить.
Посомтри, как какой-нибудь e-словарь (например Лингво) работает?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[10]: Зачем существует std::multiset
От: Alexander G Украина  
Дата: 17.06.08 10:46
Оценка:
Здравствуйте, igna, Вы писали:

I>А вот этот аргумент не понял. У слов есть значения? Можно и под этим углом посмотреть, но зачем? Например пользователь создает новую статью, и часть программы отвечающая за создание объекта Статья знает, что две части этого объекта будут храниться отдельно? Или она этого не знает, и созданный ей объект преобразуется затем к виду подходящему для хранения в multimap?


В любом случае, если у слов есть значения, нужен multimap, а не multiset. Что будет значением multimap это уже другой вопрос.
Если значений нет (орфографический словарь) то нужен set.
Русский военный корабль идёт ко дну!
Re[11]: Зачем существует std::multiset
От: igna Россия  
Дата: 17.06.08 11:19
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>В любом случае, если у слов есть значения, нужен multimap, а не multiset.


Чем multiset хуже?
Re[9]: Зачем существует std::multiset
От: igna Россия  
Дата: 17.06.08 11:46
Оценка:
Здравствуйте, Erop, Вы писали:

E>Ну не годятся стандартные контейнеры в электронных словарях.


Словарь-то не обязательно должен быть огромным. Представь изначально пустой словарь, заполняемый школьником изучающим иностранный язык. В нем будет максимум несколько тысяч слов.
Re[12]: Зачем существует std::multiset
От: Alexander G Украина  
Дата: 17.06.08 12:43
Оценка: 2 (1)
Здравствуйте, igna, Вы писали:

I>Здравствуйте, Alexander G, Вы писали:


AG>>В любом случае, если у слов есть значения, нужен multimap, а не multiset.


I>Чем multiset хуже?


Тем, что в его find, upper_bound, и другие нужно передавать то же, что хранится в нём, т.е. слово со значением.
В multimap поиск по слову находит слово и значение.
Русский военный корабль идёт ко дну!
Re[12]: Зачем существует std::multiset
От: Alexander G Украина  
Дата: 17.06.08 12:51
Оценка:
Здравствуйте, igna, Вы писали:

I>Чем multiset хуже?


Вот кстати этим


multiset: The key value of an element in a multiset may not be changed directly.
multimap: The value of an element in a multimap, but not its associated key value, may be changed directly.

Русский военный корабль идёт ко дну!
Re[13]: Зачем существует std::multiset
От: igna Россия  
Дата: 17.06.08 13:53
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>Тем, что в его find, upper_bound, и другие нужно передавать то же, что хранится в нём, т.е. слово со значением.


Строго говоря, это неверно, поскольку можно передавать dummy-значение (а не то значение, "что хранится"), но понятно, что имеется ввиду. Аргумент принят.
Re[3]: Зачем существует std::multiset
От: sokel Россия  
Дата: 17.06.08 15:30
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>Ну вот он упорядочен по d. Дальше что ? Чтобы работать теперь с диапазонами, нужны не ключи, а сами T*. Вряд ли это полезно.


такой вот несколько надуманный пример структуры с поиском по паре ключей:

#include <stdio.h>
#include <set>

struct s;
struct x_cmp { bool operator()(const s* s1, const s* s2) const; };
struct y_cmp { bool operator()(const s* s1, const s* s2) const; };

typedef std::multiset<s*, x_cmp> x_idx_type;
typedef std::multiset<s*, y_cmp> y_idx_type;
typedef x_idx_type::iterator x_iterator;
typedef y_idx_type::iterator y_iterator;

struct s
{
    s(int x, int y) : x(x), y(y) {}
    int x;
    int y;
    x_iterator x_it;
    y_iterator y_it;
};
bool x_cmp::operator()(const s* s1, const s* s2) const { return s1->x<s2->x; } 
bool y_cmp::operator()(const s* s1, const s* s2) const { return s1->y<s2->y; }

int main()
{
    x_idx_type    x_idx;
    y_idx_type    y_idx;
    for(int x=0;x<4;++x)
    {
        for(int y=0;y<4;++y)
        {
            s* ps = new s(x,y);
            ps->x_it = x_idx.insert(ps);
            ps->y_it = y_idx.insert(ps);
        }
    }
    for(x_iterator it=x_idx.begin();it!=x_idx.end();++it) printf("%d,%d;", (*it)->x, (*it)->y); printf("\n");
    // удалить все, для которых y = 2
    s key(0,2);
    std::pair<y_iterator, y_iterator> y_range = y_idx.equal_range(&key);
    y_iterator y_it = y_range.first;
    while(y_it!=y_range.second)
    {
        s* ps = *y_it;
        x_idx.erase(ps->x_it);
        y_idx.erase(y_it++);
        delete ps;
    }
    for(x_iterator it=x_idx.begin();it!=x_idx.end();++it) printf("%d,%d;", (*it)->x, (*it)->y); printf("\n");
    return 0;
}
Re[10]: Зачем существует std::multiset
От: Erop Россия  
Дата: 18.06.08 06:04
Оценка:
Здравствуйте, igna, Вы писали:

I>Словарь-то не обязательно должен быть огромным. Представь изначально пустой словарь, заполняемый школьником изучающим иностранный язык. В нем будет максимум несколько тысяч слов.

Известные мне электронные словари расчитаны на возможноть подключения очень больших словарей.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: Зачем существует std::multiset
От: Аноним  
Дата: 19.06.08 07:49
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>Кто-нибудь можеть привести пример разумного применения?


//Все очень просто 
//multiset может хотябы пригодится для случаев когда он хранит класс 
//для которого перегружен оператор меньше таким образом что сравнивается одно поле
//а второе поле игнорируется но при этом вторые поля у сравниваемых объектов могут отличаться
//здесь собсвтенно мультисет и может пригодится 
//как пример 
#include <iostream>
#include <string>
#include <set>
#include <iterator>
struct asc{ 
 int key;
 std::string value;
 asc( int k, std::string v ) : key(k),value(v) { } 
 asc( ) {} 
 bool operator < ( const asc &object ) const { 
  return key < object.key;
 } 
};

int main() { 
 std::set< asc > so;
 std::multiset< asc > sm;
 
 so.insert( asc( 1, "before" ) );
 so.insert( asc( 1, "after" ) );

 sm.insert( asc( 1, "before" ) );
 sm.insert( asc( 1, "after" ) );
 
 std::cout << "so size = " << so.size() << std::endl; //здесь мы потеряем значение
 std::cout << "sm size = " << sm.size() << std::endl; //здесь все в порядке
}
Re[2]: Зачем существует std::multiset
От: Alexander G Украина  
Дата: 19.06.08 08:14
Оценка:
Здравствуйте, Аноним, Вы писали:

А>
А>//Все очень просто 
А>//multiset может хотябы пригодится для случаев когда он хранит класс 
А>//для которого перегружен оператор меньше таким образом что сравнивается одно поле
А>//а второе поле игнорируется но при этом вторые поля у сравниваемых объектов могут отличаться
А>//здесь собсвтенно мультисет и может пригодится 
А>


Я понимаю что это будет работать, но это хуже multimap, т.к. :
Не забывайте также, что для просто key-value лучше подходят хеш-таблицы. Упорядоченное по ключу множество нужно тогда, когда требуется порядок элементов.

Всё это вместе приводит к тому, что я не могу придумать случая, когда multiset был бы правильным выбором контейнера.
Русский военный корабль идёт ко дну!
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.