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

Programming Languages and Tools:

CS:3210:0001

Lecture/Lab #28

Programming with C++

(More) sequence containers, generic algorithms, lambda expressions

Warm up: abstract classes

What's the purpose of the assert statement in line 5?

struct organism {
    virtual ~organism() {}
    virtual std::string kind() const 
    {
        assert( false ); 
        return ""; 
    }
};

struct plant : organism {
    virtual std::string kind() const 
    {
        return "plant";
    }
};

std::vector recap

  • A linear collection of objects, all of which have the same type

  • Often referred to as a container because it “contains” other objects. 

  • Similar to list in Python / ArrayList in Java

  • Every object in vector has an associated index, which gives access to that object.

v[0]

v[1]

v[v.size()-1]

...

v.capacity()

v.size()

More linear/sequence containers

list<T>

  • Doubly-linked list

  • O(1) insertion/deletion anywhere in the list

  • Bidirectional iteration (++iter, --iter)

forward_list<T>

  • Singly-linked list

  • O(1) insertion/deletion anywhere in the list

  • Forward iteration only (++iter)

  • More space-efficient then list<T>

deque<T>

array<T>

  • Doubly-ended queue

  • O(1) insertion/deletion at the front/back of the queue, O(n) insertion/deletion in the middle

  • Random-access iteration (++iter, --iter, iter += n)

  • Static contiguous array

  • Can't be resized

  • Random-access iteration (++iter, --iter, iter += n)

Generic algorithms

for ( auto& x: c )
    if ( x == value ) {
       ...
    }

for ( auto i = c.begin(); i != c.end(); ++i )
    if ( *i == value ) {
       ...
    }

Problem: finding a value in a sequence container

Solution 1:

Solution 2:

Solution 3:

auto i = find( c.begin(), c.end(), value );

Most often-used algorithms

for_each

find

find_if

count

count_if

accumulate

replace

replace_if

copy

copy_if

unique_copy

sort

equal_range

transform

Advantages of algorithms

  • Higher level of abstraction increases code clarity, makes code self-documenting
  • Correctness: manual loops are often more error prone.
  • Efficiency: algorithms are carefully tuned and optimized for special cases (e.g. copy can use memcpy when appropriate) 
  • Interoperability & reuse: expressing your data manipulations in terms of algorithms and sequences that makes using them together easier, removes friction, and increases code reuse.

Exercise 1

Sort the vector, erase all "Bob" occurrences and print the vector to the standard output using only standard algorithms

  • Open the exercise template

  • Write your code, press Run to test

  • When you're done, grab your Repl's link and send it as a direct message to me (agurtovoy)

  • Click on the corresponding option in the "Lab28 exercises" poll in #general

Made with Slides.com