Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> std::set find, insert - работа, std::set find, insert - работа 
:(
    Опции темы
Killerman
Дата 25.8.2009, 17:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 137
Регистрация: 26.10.2007

Репутация: нет
Всего: нет



У меня возник вопрос при работе с set. В нем для упорядочивания элементов по умолчанию вроде используется std::less, а если оно не устраивает, можно создать свой объект с функцией.

Я не могу понять как set определяет, что объект при вставке(insert) не повторяется. (или при поиске find найден подходящий объект)
По идее фукция ищет по упорядоченному списку объектов, и когда его не находит в set, то вставляет, иначе нет. А как функция определяет, что эти объекты равны или не равны?

Это типа в объекте нада перегрузить фуекцию operator == ?

Это сообщение отредактировал(а) Killerman - 25.8.2009, 17:12
PM MAIL   Вверх
IKM2007
Дата 25.8.2009, 17:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Зима близко
**


Профиль
Группа: Участник
Сообщений: 702
Регистрация: 26.4.2008
Где: olmedreca

Репутация: нет
Всего: 40



Цитата(Killerman @  25.8.2009,  17:10 Найти цитируемый пост)
А как функция определяет, что эти объекты равны или не равны?

Скорее функция определяет, эквивалентны элементы, или же нет. Равность и эквивалентность разные вещи.

Добавлено через 4 минуты и 29 секунд
Цитата(Killerman @  25.8.2009,  17:10 Найти цитируемый пост)
то объект при вставке(insert) не повторяется

Здесь проверяется отношение эквивалентности, критерием сравнения используется std::less<T>.

Цитата(Killerman @  25.8.2009,  17:10 Найти цитируемый пост)
или при поиске find найден подходящий объект

При find элементы сравниваются, то есть используется operator ==.


--------------------
"К чёрту обстоятельства, я создаю возможности."
Брюс Ли
PM MAIL Skype   Вверх
mes
Дата 25.8.2009, 17:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(Killerman @  25.8.2009,  16:10 Найти цитируемый пост)
Это типа в объекте нада перегрузить фуекцию operator == ?

equal можно получить опираясь на less :
Код


bool is_equal (const A& lhs, const A& rhs)
{
     return ! (lhs < rhs || rhs < lhs); 
}

 smile 

Это сообщение отредактировал(а) mes - 27.8.2009, 01:09


--------------------
PM MAIL WWW   Вверх
Killerman
Дата 25.8.2009, 18:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 137
Регистрация: 26.10.2007

Репутация: нет
Всего: нет



спасибо. попробую
PM MAIL   Вверх
Killerman
Дата 27.8.2009, 00:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 137
Регистрация: 26.10.2007

Репутация: нет
Всего: нет



Я в шоке! при 100 объектах в массиве set.find по ключу int ищет на 2-ве секунды дольше чем при последовательном переборе. Это нормально?

(имелось ввиду при множественном колличестве операций поиска)

Это сообщение отредактировал(а) Killerman - 27.8.2009, 01:06
PM MAIL   Вверх
andrew_121
Дата 27.8.2009, 01:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: 6
Всего: 33



Цитата(Killerman @  27.8.2009,  00:54 Найти цитируемый пост)
Это нормально?

Это ваще не нормально! Две секунды, для компа вечность smile 


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
Killerman
Дата 27.8.2009, 01:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 137
Регистрация: 26.10.2007

Репутация: нет
Всего: нет



ну это может на нескольких десятках тысяч операций поиска. точно не скажу. факт в том что ищет по дереву медленнее чем простым перебором в лоб. и что с этим делать?
может есть какой то другой адекватный класс может в другой библиотеке?

у меня в массиве указатели на объекты, а поиск нужно вести по элементу этих объектов (в данном случае по int члену класса).

Это сообщение отредактировал(а) Killerman - 27.8.2009, 01:38
PM MAIL   Вверх
andrew_121
Дата 27.8.2009, 01:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: 6
Всего: 33



Посмотри на это: http://www.google.ru/search?hl=ru&neww...ash+map+c%2B%2B
И в часности на это: http://www.epsilon-delta.net/code/hashmap.html

Добавлено @ 01:58
Если используешь компилятор от микрософт, посмотри на: http://msdn.microsoft.com/en-us/library/6x7w9f6z(VS.80).aspx
Я так понял, что hash_map<> в стандарт не входит.

Это сообщение отредактировал(а) andrew_121 - 27.8.2009, 01:58


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
azesmcar
Дата 27.8.2009, 08:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(Killerman @  27.8.2009,  00:54 Найти цитируемый пост)
Я в шоке! при 100 объектах в массиве set.find по ключу int ищет на 2-ве секунды дольше чем при последовательном переборе. Это нормально?


Нет, это ненормально, в set поиск имеет логарифмическую сложность, а значит поиск в нем будет намного быстрее чем последовательный перебор (который имеет линейную сложность).

Покажи свой код.
PM   Вверх
Killerman
Дата 27.8.2009, 15:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 137
Регистрация: 26.10.2007

Репутация: нет
Всего: нет



Код примерно такой:

Код

//класс для поиска
    class less_myClass
  {      
   public:
      bool operator() (SetObj * c1, SetObj * c2)
    {
         return (c1->i < c2->i);
    }      
 };


std::set<SetObj *,less_myClass> arrayofSetObj;


//потом вставка идет как:

arrayofSetObj.insert(PtrsetObj1);

//а поиск как:

std::set<SetObj *,less_myClass>::const_iterator Iter1 = arrayofSetObj.find(PtrsetObj2);
if(Iter == arrayofSetObj.end())
   return false;



/////////////////////////////////////
Может просто объектов слишком мало в set (рост списка шел от 0-ля до 110), чтобы видить преимущество такого поиска.

Но у меня сначало был список не set, а vector, так при работе с вставкой и поиском суммарное время было большим, а когда я переделал в set - стало еще больше!!!

Может это связано и с тем что вставка в vector  идет быстро (в произвольном месте), а при вставке в set происходит тот же поиск как при set.find, чтобы вычеслить куда вставлять элемент.

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


PM MAIL   Вверх
azesmcar
Дата 27.8.2009, 15:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Killerman

Да, вставка в set медленнее чем в vector (если не учитывать reallocation-а в векторе), но вопрос был про поиск а не про вставку. 

что-то ты не договариваешь или не показываешь всего...покажи мне код, который у тебя на две секунды дольше работает, это с 110 элементами??? О каких секундах идет речь? smile 
PM   Вверх
Killerman
Дата 27.8.2009, 15:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 137
Регистрация: 26.10.2007

Репутация: нет
Всего: нет



Это весь код с использованием set. просто там закручены разные усдовия что типа если нашло - то делать то, если нет то то. Алгоритм программы не имеет отношения к реализации set и list.

если тупо заменить list на set, ничего не меняя больше (только в list вместо find перебирались все элементы и сравнивались с одним, и еще в list вставлялись в конце, а в set - через insert ) то программа с list выполняется 67 секунд, а с set 69.
PM MAIL   Вверх
bsa
Дата 27.8.2009, 15:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Killerman, все прелести сложных объектов вроде set могут быть обнаружены при большом количестве объектов. А в большинстве случаев рекомендуется пользоваться vector.
PM   Вверх
mes
Дата 27.8.2009, 15:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(Killerman @  27.8.2009,  14:42 Найти цитируемый пост)
только в list вместо find перебирались все элементы и сравнивались с одним, и еще в list вставлялись в конце, а в set - через insert )

 smile 
Один мужик ищет под фонарем - рубль потерял. Другой вызвался ему помочь. 
Через некоторе время второй уточняет : " а где именно ты потерял ?".
Первый, показывая в даль рукой, говорит "где то там..."
Второй : "ну а почему мы здесь то ищем ?!"
Первый: "так тут светлей !.."

Это к слову о том, что обвиняя find, Вы забыли об упоминании inserta, который судя по всему и служит тормозом в вашем случае.



Это сообщение отредактировал(а) mes - 28.8.2009, 10:20


--------------------
PM MAIL WWW   Вверх
azesmcar
Дата 27.8.2009, 15:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Killerman

1. Как я уже сказал - insert в list-е быстрее чем insert в set -е, но вопрос был про поиск, а поиск у set -а быстрее работает
2. Если говорят что алгоритм эффективнее, это не значит что он ВСЕГДА будет работать быстрее, если будешь искать элемент, который в списке первый, то линейный обход списка будет быстрее. 

В общем тебе надо сперва подумать о том, что тебе нужно, скорость вставки или скорость поиска.
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0889 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.