![]() |
|
|
![]()
|
|
| Нитонисе |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 917 Регистрация: 5.11.2009 Репутация: 2 Всего: 2 |
Заполняю контейнер vector элементами типа float. Нужно удалить одинаковые значения, но этого не происходит из-за того, что после запятой у казалось бы одинаковых элементов - идут неодинаковые знаки.
Так, добавив в контейнер два числа 2.6 - одно из них не удалится из контейнера, потому что одно хранится в виде 2.6000000123, а второе в виде 2.59999999999123. Это неизлечимо? |
|||
|
||||
| Cheloveck |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1578 Регистрация: 26.7.2008 Где: Тула Репутация: 1 Всего: 32 |
Округли до значимых разрядов и сравнивай
-------------------- ![]() |
|||
|
||||
| Нитонисе |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 917 Регистрация: 5.11.2009 Репутация: 2 Всего: 2 |
||||
|
||||
| fry |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 257 Регистрация: 4.10.2006 Репутация: нет Всего: 3 |
Сделай функцию сравнения вида:
float delta(f1-f2); delta=delta>0 ? delta: -delta; return (delta<MAX_DELTA) ? 1: 0; Это сообщение отредактировал(а) fry - 26.12.2009, 08:18 |
|||
|
||||
| Нитонисе |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 917 Регистрация: 5.11.2009 Репутация: 2 Всего: 2 |
||||
|
||||
| mrbrooks |
|
|||
![]() трололомен ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4259 Регистрация: 4.10.2006 Где: Дол Гулдур Репутация: 167 Всего: 306 |
Нитонисе, для твоих целей более подходит std::list
|
|||
|
||||
| Usper |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 325 Регистрация: 13.4.2007 Репутация: 15 Всего: 15 |
Нитонисе, у fry подход правильный, но реализация странная, при этом без соблюдения синтаксиса приплюснотого Си
З.Ы. вектор тут совсем не причём. -------------------- На посохе волшебном нехилый набалдашник, большой такой, огромный, нехилый набалдашник. |
|||
|
||||
| fry |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 257 Регистрация: 4.10.2006 Репутация: нет Всего: 3 |
А дубликат это или нет ты как узнаешь? (Ответ см. в первом посте).
Обходишь вектор, смотришь какие рядом значения, если функция возвращает 1, то удаляешь одно из них.
.....хм, а где ошибся? Млин, пока отвечали на "хм, а где ошибся?" сам проверил. Все ОК. Это сообщение отредактировал(а) fry - 26.12.2009, 09:19 |
|||
|
||||
| mrbrooks |
|
|||
![]() трололомен ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4259 Регистрация: 4.10.2006 Где: Дол Гулдур Репутация: 167 Всего: 306 |
||||
|
||||
| fry |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 257 Регистрация: 4.10.2006 Репутация: нет Всего: 3 |
Эт точно. Поддерживаю.
|
|||
|
||||
| Usper |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 325 Регистрация: 13.4.2007 Репутация: 15 Всего: 15 |
А, и вправду, синтаксических ошибок нет , я спросонья подумал, что это и есть вся функция. Приношу свои извинения.
mrbrooks, а как в std::list реализована функция unique()? Возможно, здесь будут те же проблемы, что и при обычном сравнивании чисел с плавающей точкой. Это сообщение отредактировал(а) Usper - 26.12.2009, 10:15 -------------------- На посохе волшебном нехилый набалдашник, большой такой, огромный, нехилый набалдашник. |
|||
|
||||
| Нитонисе |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 917 Регистрация: 5.11.2009 Репутация: 2 Всего: 2 |
||||
|
||||
| mrbrooks |
|
|||
![]() трололомен ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4259 Регистрация: 4.10.2006 Где: Дол Гулдур Репутация: 167 Всего: 306 |
||||
|
||||
| Нитонисе |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 917 Регистрация: 5.11.2009 Репутация: 2 Всего: 2 |
Точно что могут быть проблемы, потому что у меня некоторые и в векторе удаляются, потому что хранятся красиво, без лишних знаков после запятой. А некоторые не хотят так хранится и потому вектор их считает различными значениями, несмотря на то что отличие в 8-ом знаке после запятой. И лист тоже. |
|||
|
||||
| mrbrooks |
|
|||
![]() трололомен ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4259 Регистрация: 4.10.2006 Где: Дол Гулдур Репутация: 167 Всего: 306 |
Нитонисе, приведи код как ты заполняешь контейнер.
|
|||
|
||||
| Usper |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 325 Регистрация: 13.4.2007 Репутация: 15 Всего: 15 |
mrbrooks, проведи простой тест:
Думаю, ты удивишься У меня это привело к следующему:
З.Ы. контейнер здесь вообще не причём, это проблема представления действительного числа, и она существует не только в C++. Для сравнения двух чисел с плавающей точкой нужен подход, предложенный fry`ем. Это сообщение отредактировал(а) Usper - 26.12.2009, 13:14 -------------------- На посохе волшебном нехилый набалдашник, большой такой, огромный, нехилый набалдашник. |
||||
|
|||||
| mrbrooks |
|
||||
![]() трололомен ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4259 Регистрация: 4.10.2006 Где: Дол Гулдур Репутация: 167 Всего: 306 |
неа. отчего же. я знаю как представляется число с плавающей точкой
я что то говорил про проблемы контейнера и против предиката? Добавлено через 1 минуту и 50 секунд Usper, ах да. я же привел пример Добавлено через 5 минут и 53 секунды Usper, ах да. я же привел пример Добавлено через 10 минут и 38 секунд
|
||||
|
|||||
| Usper |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 325 Регистрация: 13.4.2007 Репутация: 15 Всего: 15 |
Тогда ты должен понимать, что в этом случае:
может быть непредсказуемый результат. И всё упирается в реализацию определения одинаковых элементов в списке. Если там простое сравнение в одном случае из тысячи (а может быть и гораздо чаще, а может быть и гораздо реже) мы можем получить два одинаковых (с нашей точки зрения, но не одинаковых с точки зрения компьютера) элемента. Этот тупой пример я привёл чтобы как раз это продемонстрировать. В 60% случаем у нас правильный с нашей точки зрения результат, зато в оставшихся полная фигня. Если ты получил нормальный результат в результате работы своего примера это говорит как о том, что пример действительно работает правильно в любом случае, так и о том, что тебе просто повезло. Я поэтому и спрашиваю, ты знаешь как реализовано определение одинаковых элементов в конкретной библиотеке? -------------------- На посохе волшебном нехилый набалдашник, большой такой, огромный, нехилый набалдашник. |
||||
|
|||||
| mrbrooks |
|
|||
![]() трололомен ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4259 Регистрация: 4.10.2006 Где: Дол Гулдур Репутация: 167 Всего: 306 |
Usper, конечно же нет.
|
|||
|
||||
| Нитонисе |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 917 Регистрация: 5.11.2009 Репутация: 2 Всего: 2 |
Извиняюсь, речь изначально шла о list, а не о vector. В векторе нет функций удаления дубликатов и сортировки. Я сначала закидывал все в лист, хотел там сортировать и удалять дубликаты, а потом перекинуть в вектор.
Это сообщение отредактировал(а) Нитонисе - 26.12.2009, 14:20 |
|||
|
||||
| mrbrooks |
|
|||
![]() трололомен ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4259 Регистрация: 4.10.2006 Где: Дол Гулдур Репутация: 167 Всего: 306 |
Совершенно верно. Но к std::vector можно применить алгоритмы std::sort и std::unique - однако это не оптимально. Если у тебя нет конкретных требований к точности заполняй контейнер через функцию fabs. Типа этого:
|
|||
|
||||
| Нитонисе |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 917 Регистрация: 5.11.2009 Репутация: 2 Всего: 2 |
||||
|
||||
| Usper |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 325 Регистрация: 13.4.2007 Репутация: 15 Всего: 15 |
Так в чём проблема использовать метод, предложенный fry`ем? Можно просто в цикле сравнивать все элементы вектора и удалять их "вручную".
-------------------- На посохе волшебном нехилый набалдашник, большой такой, огромный, нехилый набалдашник. |
|||
|
||||
| Нитонисе |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 917 Регистрация: 5.11.2009 Репутация: 2 Всего: 2 |
Я так и делаю. Просто я говорю что функция удаления дубликатов в list не работает для типа float, |
|||
|
||||
| mrbrooks |
|
|||
![]() трололомен ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4259 Регистрация: 4.10.2006 Где: Дол Гулдур Репутация: 167 Всего: 306 |
||||
|
||||
| Нитонисе |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 917 Регистрация: 5.11.2009 Репутация: 2 Всего: 2 |
||||
|
||||
| narmo |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 5 Регистрация: 25.8.2007 Репутация: нет Всего: нет |
x.xf - просто указывает, что вышеозначенное число - с плавающей точкой.
Числа с плавающей точкой НЕ ПРЕДНАЗНАЧЕНЫ для сравнения на равенство посредством операции "==". Попытки это сделать - издевательство над здравым смыслом. Вам правильно сказали, задайте свою операцию сравнения с помощью предиката или как-либо ещё. Хоть в структуру упакуйте и определите для неё операцию "==", хоть просто пишите алгоритм с циклами и условием равенства x1-x2<epsilon:) Это сообщение отредактировал(а) narmo - 28.12.2009, 15:58 |
|||
|
||||
| mrbrooks |
|
|||
![]() трололомен ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4259 Регистрация: 4.10.2006 Где: Дол Гулдур Репутация: 167 Всего: 306 |
narmo, давай по пятьдесят раз каждый учасник повторит про вызов list.unique() с предикатом
|
|||
|
||||
![]()
|
| Правила форума "С++ Builder" | |
|
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C++ Builder | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |