STL как контейнер с O (1) производительность

У Marcus Zarra есть довольно ясная позиция по этому: , "Если Вы имеете дело с валютой вообще, тогда необходимо использовать NSDecimalNumber". Его статья вдохновила меня изучать NSDecimalNumber, и я был очень впечатлен им. Ошибки плавающей точки IEEE при контакте с основой, 10 математики раздражала меня некоторое время (1 * (0.5 - 0.4 - 0.1) =-0.00000000000000002776) и NSDecimalNumber, покончили с ними.

NSDecimalNumber только добавляет другого немного цифр двоичной точности с плавающей точкой, он на самом деле основывает 10 математики. Это избавляется от ошибок как один показанный в примере выше.

Теперь, я пишу символьное математическое приложение, таким образом, мое требование 30 + точность десятичной цифры и никакие странные ошибки с плавающей точкой могли бы быть исключением, но я думаю, что на это стоит посмотреть. Операции являются немного более неловкими, чем простой var = 1 + 2 математики стиля, но они все еще управляемы. Если Вы волнуетесь по поводу выделения всех видов экземпляров во время Ваших математических операций, NSDecimal является структурой C, эквивалентной из NSDecimalNumber и существуют функции C для того, чтобы сделать те же самые математические операции с ним. По моему опыту, они - много быстро для всех кроме большинства требовательных приложений (3 344 593 дополнения/с, 254 017 подразделений/с на MacBook Air, 281 555 дополнений/с, 12 027 подразделений/с на iPhone).

Как добавленная премия, descriptionWithLocale NSDecimalNumber: метод предоставляет строке локализованную версию числа, включая корректный десятичный разделитель. То же идет наоборот для его initWithString:locale: метод.

5
задан rmeador 21 October 2009 в 16:01
поделиться

7 ответов

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

Удалить элемент, пометив его как удаленный, вставить элемент в корзину в желаемой позиции и запомнить смещение для больших индексов.

Вставки и удаления будут очищать O (1) плюс O (N) в удобное время; поиск будет иметь значение O (1) в среднем, O (количество изменений с момента последней очистки) в худшем случае.

1
ответ дан 18 December 2019 в 09:08
поделиться

Не существует абстрактного типа данных со сложностью O (1) для вставки, стирания и поиска, который также обеспечивает итератор двунаправленного доступа .

Изменить:

Это верно для произвольно большого домена. Учитывая достаточно маленький домен, вы можете реализовать набор со сложностью O (1) для Insert, Стирание и поиск и итератор двунаправленного доступа с использованием массива и двусвязного списка:

std::list::iterator array[MAX_VALUE];
std::list list;

Инициализация:

for (int i=0;i<MAX_VALUE;i++)
    array[i] = list.end();

Вставка:

if (array[value] != list.end())
    array[value] = list.insert(value);

Стереть:

if (array[value] != list.end()) {
    array[value].erase();
    array[value] = list.end();
}

Поиск:

array[value] != list.end()
10
ответ дан 18 December 2019 в 09:08
поделиться

tr1's unordered_set (also available in boost) is probably what you are looking for. You don't specify whether or not you want a sequence container or not, and you don't specify what you are using to give O(1) lookup (ie. vectors have O(1) lookup on index, unordered_set mentioned above has O(1) average case lookup based on the element itself).

4
ответ дан 18 December 2019 в 09:08
поделиться

Associative arrays (hashtable) have O(1) lookup complexity, while doubly linked lists have O(1) bidi iteration.

1
ответ дан 18 December 2019 в 09:08
поделиться

Вы не сможете уместить все свои требования в один контейнер ... что-то нужно дать;) Однако, может быть, вам это интересно: http://www.cplusplus.com/reference/stl/

0
ответ дан 18 December 2019 в 09:08
поделиться

Полный список всех гарантий сложности для STL можно найти здесь:
Каковы гарантии сложности стандартных контейнеров?

Резюме:


  • Вставка: Нет контейнера Гарантия O (1) для универсальной вставки.
    • Единственный контейнер, в котором есть gurtantee, - это «Ассоциативный контейнер». И это O (ln (n))
  • Есть контейнеры, которые обеспечивают ограниченную гарантию вставки

    • Прямая секвенция гарантирует вставку в начале O (1)
    • Задняя последовательность гарантирует вставку в конце O (1) )
  • Стереть

    • Ассоциативные контейнеры гарантируют O (1) для стирания (если у вас есть итератор).
  • Поиск:

    • Если вы имеете в виду доступ к элементу путем поиска (поскольку ни один контейнер не имеет возможности поиска O (1)).
    • Тогда контейнер произвольного доступа является единственным контейнером с доступом O (1)

Итак, ответ основан на типах контейнеров.
This is what the standard gurantees are defiend for how does this translate to real containers:

std::vector:    Sequence,   Back        Sequence,                   Forward/Reverse/Random Container
std::deque:     Sequence,   Front/Back  Sequence,                   Forward/Reverse/Random Container
std::list:      Sequence,   Front/Back  Seuqence,                   Forward/Reverse Container
std::set:       Sorted/Simple/Unique    Associative Container,      Forward Container
std::map:       Sorted/Pair/Unique      Associative Container,      Forward Container
std::multiset:  Sorted/Simple/Multiple  Associative Container,      Forward Container
std::multimap:  Sorted/Pair/Multiple    Associative Container,      Forward Container
1
ответ дан 18 December 2019 в 09:08
поделиться

Одна уловка, которую я сделал, когда возился с оптимизацией хранилища, - это реализовать связанный список с добавлением O (1) [1], а затем выполнить операцию кэширования, которая предоставляет структуру с более быстрый поиск O (n) [2]. Фактический кеш создается за O (n) времени, и я не сосредоточился на стирании. Так что я немного «схитрил» и переложил работу на другую операцию. Но если вам не нужно делать кучу добавлений / удалений, это неплохой способ сделать это.

[1] Сохранить указатель конца и добавлять только в конец. Обход не требуется.
[2] Я создал динамический массив [3] и провел поиск по нему. Поскольку данные не были отсортированы, я не мог использовать binsearch против них в течение O (lg n) времени. Хотя, полагаю, я мог бы его отсортировать.
[3] Массивы имеют лучшую производительность кеширования, чем списки.

1
ответ дан 18 December 2019 в 09:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: