The University of Iowa
The College of Liberal Arts and Sciences
Department of Computer Science

Programming Languages and Tools:

CS:3210:0001

Lecture/Lab #24

Programming with C++

Algorithmic complexity, multimap/multiset, unordered associative containers

Warm up

A good "debug mode" should catch all of the standard library's DO NOTs for all of the standard library containers

GCC

Define _GLIBCXX_DEBUG macro, e.g.

g++ --std=c++17 -D_GLIBCXX_DEBUG

clang

Set _LIBCPP_DEBUG macro to 1, e.g.

clang++ --std=c++17 -D_LIBCPP_DEBUG=1

MSVC

Set _ITERATOR_DEBUG_LEVEL macro to 2, e.g.

cl /std:c++17 /D_ITERATOR_DEBUG_LEVEL=1

Algorithmic complexity

  • Each container's member function comes with an asymptotic complexity specification, e.g.
map<Key,V>::operator[]

Complexity

O(log n) / Logarithmic in the size of the container

map size

[] complexity

10

3.32

100

6.64

1,000

9.96

10,000

13.29

100,000

16.61

1,000,000

19.93

A measure of how long an algorithm would take to complete given an input of size `n`

Algorithmic complexity (cont.)

  • Complexity guarantees are an important part of the container/operation's behavior; a standard library implementation that doesn't deliver on these guarantees is likely to make your program unusable.
  • Unless explicitly stated otherwise, complexity guarantees specify worst case performance.
  • Average case performance guarantees assume that container elements are chosen from a finite type with more possible values than the size of the container, and that container elements are independently uniformly distributed.

logarithmic

n = 1,000,000

complexity = 19.93

linear

n = 1,000,000

complexity = 1,000,000

"Big O" notation

O(1)

Constant time; will always execute in the same time regardless of the size of the input data set.

Examples: dereferencing an iterator (*iter), indexing array element (a[i])

O(n)

Linear time; execution time is directly proportional to the input size.

Examples: finding a minimum, linear search in an array

O(n²)

Quadratic time; execution time is directly proportional to the square of the size of the input data set.

Examples: bubble sort

O(log n)

Logarithmic time; execution time execution is proportional to the binary logarithm of the input size.

Examples: binary search

A (mathematical) notation for concisely describing asymptotic complexity

Associative Containers

Fast retrieval of data based on keys

[Ordered] Associative Containers

Require an ordering function (operator < by default) and yield an ordered sequence;

O(log n) lookup/insertion/deletion time.

Unordered Associative Containers

— Require a hash function and do not maintain an order among its elements;

O(1) average lookup/insertion/deletion time;

O(n) worst-case lookup/insertion/deletion time.

  • map<Key,T>

  • multimap<Key,T>

  • set<T>

  • multiset<T>

  • unordered_map<Key,T>

  • unordered_multimap<Key,T>

  • unordered_set<T>

  • unordered_multiset<T>

multimap/multiset

struct gps_coords {
    double x;
    double y;
};

struct car {
    std::string license_plate;
    gps_coords position;
};


struct car_tracker
{
    std::multiset<car> cars;
    std::vector<car> cars_by_position( gps_coords const& ) const;
};

Use case: grouping objects that are related together by key

std::[multi_]map/set iterator operations

auto iter = c.erase( pos );

Removes the element at pos.

auto iter = c.erase( first, last );

Removes the elements in the range [first, last).

Invalidates iterators and references to the erased elements, other iterators and references are not affected.

auto iter = c.insert( v );

Inserts element v.

auto iter = c.insert( first, last );

Inserts elements from range [first, last).

No iterators or references are invalidated.

auto [first, last] = c.equal_range( k );

Returns a range containing all elements with the given key in the container.

first points to the first element that is not less than key, last points to the first element greater than key.

Unordered Associative Containers

  • Require a hash function and do not maintain an order among its elements
  • unordered_map<Key,T>

  • unordered_multimap<Key,T>

  • unordered_set<T>

  • unordered_multiset<T>

  • O(1) average lookup/insertion/deletion time
  • O(n) worst-case lookup/insertion/deletion time
  • Default hash function implementation (std::hash<T>) for std::string and all the basic integral type keys comes with the standard library

Programming with C++, Spring 2020, Lecture #24

By Aleksey Gurtovoy

Programming with C++, Spring 2020, Lecture #24

Algorithmic complexity, multimap/multiset, unordered associative containers

  • 457