Title: C for Java Programmers
1C for Java Programmers
- Lecture 13
- Vectors, Maps Lists
2Last term in CFJ
- waaay back last week we discussed
- Template Functions
- Template Classes
- The Standard Template Library
- String Class
- Documentation
- Coursework 2
3Todays action
- To start with were just going to get up to
speed - Templates
- The Standard Template Library
- Containers, Algorithms and Iterators
- And then look in much more detail at some vital
structures - Vectors
- Lists
- Maps
- The Short Answer Test
41. Templates Refresher
- Templates are somewhere near the peak of Object
Orientation because they allow you to create
completely reusable code - Pretty novel but now completely standard in the
C world. - Remember templates are used for creating generic
functions and classes. - We tell the template what type of data to use
when we create an instance of it and we can
feed it anything.
5Class Templates
- Remember the syntax for a template class
- template ltclass Xgt class sausage
-
- //everything you would have in a normal
class - //but using X to declare data with
-
- Then to create a specific instance of this class
use the form - sausage ltintgt mySausage
- Now when we look back at the template class we
can substitute every use of class X for an
integer and know this is how the class will work
for mySausage.
6Example Template Class
Code for our template class
- template ltclass Xgt class Couple
- public
- string name
- X value
- Couple(string n, X v) name n value v
- void double() value value value
-
- int main()
- Couple ltfloatgt decimal(Pi, 3.14)
- Couple ltstringgt text(Pie, Steak and Kidney)
- decimal.double()
- text.double()
Double works differently in each case. but works
7Use Templates
- Templates can be incredibly useful
- You can create frameworks that you can apply and
reapply. (E.g. sorting classes) - Once theyre working they become the most
re-usable code you will write. - The idea of Templates has proven to be so good
that there is a whole library of pre-written
templates in C. This is the Standard Template
Library.
8Standard Template Library
- STL gives you huge flexibility and is extremely
popular in professional programming circles. - Its popular because its good Java has borrowed
a lot of ideas from it. - Dont be put off using them they are here to
make your life easier. - The vital point is just picking the right
template for the problem in hand.
9STL fundamentals
- At the core of the STL are three conceptual
items, that allow us to use create usable
objects - Crucially these combine together. You use
algorithms and iterators on the container you
have chosen.
containers
algorithms
iterators
10Types of Containers
- Remember that there are 3 types of Containers
Linear Lists Examples are Vector class List
class String class
Sequences
Paired containers Examples are Map
class multiset class Multimap class
Associative
Adapted from other containers queue class stack
class priority_queue
Adapted
11Algorithms
- Every class in the STL has common features.
- Because of this there are special algorithms that
you can use on lots of different template
classes. - Lots of generic algorithms are available in
ltalgorithmgt - there are in fact more than 70 in
the library. - Examples are min(), max(), search(), sort()
12Iterators
- An iterator is a kind of generalised pointer that
we can used to traverse the elements of a
container. - At any point in time an iterator is positioned at
exactly one place in a collection, and will
remain there until moved. - These iterators are vitally important for moving
around your container. Not only that, the STL
Algorithms almost all use these special pointers
too. For example - min_element() - returns an iterator to the min
element in a range
13Remember Strings are in the STL
- A String class was grudgingly implemented into
the STL its a type of list and hence is a
Sequence Container. - This was because that although using null
terminated string makes you a good person, they
do have their weaknesses. - You Have to use strcpy all the time and cant use
simple operators. You can easily run into bugs
too String objects add safety to your coding.
14STL Strings mean we can use
- Assignment
- Concatenation
- Concatenation Assignment
- Equality
- ! Inequality
- lt Less than
- lt Less than or equal
- gt Greater than
- gt Greater than or equal
- Subscripting
- ltlt Output
- gtgt Input
Remember any class you write you can overload
these operators use the friend facility
15Methods now Available
- append() - concatenate more text to the string
- substr() - cut out a substring of some size
- insert() - add some text into the string
- replace() - replace part of a string
- erase() - delete part of a string
- assign() - flexible way of assigning text
- compare() - lexically compare two stings
- find() - search for some text in the string
- rfind() - find some text - backwards
- c_str() - return the null-terminated version
162. Okay back at the ranch
- The three most important templates that you need
to be aware of are - vectors
- lists
- maps
- These dont necessarily work how you might expect
and are quite different to their counterparts in
Java. - We will consider these popular templates, how we
could use them, and how we can apply algorithms
to them.
17Vectors
- The Vector Class is the dominant list
representation and housed in the ltvectorgt
library. - lt is essentially a dynamic array and very
similar to the Java Vector object. - It provides four constructors for defining a list
of elements - default constructor for an empty vector
- A copy constructor to copy and existing vector
- A constructor with a parameter telling us the
lists initial size - A constructor with two parameters the size of
the vector and the value that its data is
initialised with.
18Setting up those Vectors
- So all of the following declarations are valid
- const int N20
- const int M40
- int length
- cout ltlt Enter size of vector
- cin ltlt length
- vectorltintgt A(10)
- vectorltfloatgt C(M)
- vectorltintgt D(length)
- vectorltJPPvariablegt E(N)
vector of 10 integers
vector of 40 floats
vector of length ints
20 JPPvariable vector
19And initialising them too
vector of 10 ints with a value of 2
- vectorltintgt J(10,2)
- vectorltchargt K(5, a)
- Coordinate point new Coordinate(3,3)
- vectorltCoordinategt C(10, point)
- vectorltintgt K(J)
- You can assign one vector to another using the
operator so long as they are of the same lttypegt.
vector of 5 chars all with a value of a
vector of Coordinates all initialised as (3.3)
Intitialising one vector using another
20Common Vector Mistake
- Consider the following code. What type of object
is A? -
- vector ltintgt A10
- Object A is not a vectorltintgt object with 10
elements of type integer. - Rather, the object A is in fact an array of size
10, whose elements themselves are vectors. - The reason is because the 10 is contained within
square brackets not parentheses. We didnt call
the vectors constructor at allwe set up an array.
21Member Functions
- The most commonly used member functions are
- If you are using a vector photocopy the member
functions from a page in your textbook there
are lots. It will save you lots of time and make
your coding much more effective.
size() - returns the vectors current
length begin() - returns an iterator to
the start of the vector end() - returns an
iterator to the end of the vector push_back()
- puts a value on the end of the vector insert()
- inserts an element anywhere in the
vector erase() - Remove an element
22Overloaded Vector Operators
Assignment Equality !
Inequality lt Less than lt Less than or
equal gt Greater than gt Greater than or
equal Subscripting
- By overloading a template we have a really
flexible structure which we can now often treat
in the same way we do a fundamental type.
So even though we have a vector we can access
elements in the same way as an array
23Another CrAzY Example
- void display(vectorltchargt temp)
- cout ltlt size ltlt v.size() ltlt endl
- for(int i0 ilttemp.size() i) cout ltlt tempi
ltlt -
- int main()
- vectorltchargt v(10)
-
- for(int i0 ilt10 i) vi i a
- display(v)
- for(int i0 iltv.size() i) v.push_back(i10a
) - display(v)
- for(int i0 iltv.size() i) v.itoUpper(vi)
- display(v)
initialise the values
expand the vector
24Accessing using an Iterator
- When we looked at arrays we saw that we could
access individual elements through subscripting
or by using a pointer. - In just the same way we can access the elements
of a vector through subscripting or using an
iterator. To create an iterator we use the
syntax - vector lttypegtiterator name
- In practice this looks something like
- vector ltchargtiterator p
25Iterators in Action
- int main()
- vectorltchargt v(10)
- vectorltchargtiterator p v.begin()
- int i0
- //display the contents of the array
- for(int i0 p ! v.end() p, i) p
ia - //display the contents of the array
- p v.begin()
- for( p ! v.end() p) cout ltlt p ltlt endl
- //convert to uppercase
- for(p v.begin() p ! v.end() p) p
toUpper(p)
26Inserting and Deleting elements
- insert() and erase() add and remove elements from
a vector -
- vectorltchargt v(10)
- vectorltchargtiterator p v.begin()
- p 2
- v.insert(p , 10, X)
- v.insert(p1 , v2.begin(), v2.end() )
- v.erase (p)
- v.erase (p1 , p5)
insert 10 chars of value X at the 3rd element
insert a whole vector v2 at the 4rd element
removes the element pointed to by p
removes the next 4 elements
27Storing Class Objects
- Weve only stored elements in the above examples
of built in types but we can of course use class
objects. - All of the commands function in exactly the same
way for object elements there is no difference
at all. For example - vector ltBananagt bunch(7)
- vector ltBananagtiterator b bunch.begin()
- cout ltlt bunch.size ltlt endl
- for( b ! bunch.end() b) cout ltlt b ltlt endl
- bunch.erase( bunch.begin(), 3)
- bunch.pop_back()
28This is Different to Java
- Straight away it is clear that vectors in C are
not the same as in Java. - The primary difference in Java is that the
contents of a vector must be an object. Because
of this you often have the hassle of wrapper
classes.not so in C. - Another difference is that in C the vectors
must all be of the same type, which can be
constrictive. - So if we are left with the fact that we can only
put objects of one type in a vectorcan we work
around it?
29A solution rears its head.
- There are several ways of getting round this
problem we could use another container. - But we can often use a vector full of pointers to
objects as opposed to the objects themselves. - Now we can use the rules of inherited classes
- A pointer to a parent class, can also point to a
derived class.
30Vector Power
myVector
stack
myVector0
myVector1
myVector2
myVector3
JPPVariable pointers
heap
313. Lists
- The list class supports a bi-directional, linear
list. This is essentially a Linked List. - Lists only support sequential access.This differs
greatly to vectors which support random access
you cannot use subscripting with a list. - Setting up a list is very similar to a vector
- list ltintgt A(10)
- list ltchargt D(x, a)
- list ltJPPvariablegt E(otherList)
list of 10 integers
list of x floats,set as a
List of JPPvariables, copied from otherList
32Its all just a linked list
list
stack
Fptr
variable
Bptr
Fptr
variable
null
Fptr
variable
Bptr
null
variable
Bptr
heap
33Member Functions
- The most commonly used member functions are
size() - returns the lists current
length begin() - returns an iterator to
the start of the list end() - returns an
iterator to the end of the list insert()
- inserts an element anywhere in the
vector erase() - Remove an
element push_back() - puts a value on the end
of the vector push_front() - puts a value on
the start of the vector splice() - Join two
lists together merge() - merges two lists
together
size() - returns the lists current
length begin() - returns an iterator to
the start of the list end() - returns an
iterator to the end of the list insert()
- inserts an element anywhere in the
vector erase() - Remove an
element push_back() - puts a value on the end
of the vector
34Lets add 100 to numbers
- int main()
- listltintgt myList
-
- for(int i0 ilt10 i) myList.push_back(i)
- cout ltlt Size ltlt myList.size() ltlt endl
- listltintgtiterator p myList.begin()
- for( p ! myList.end() p) cout ltlt p ltlt
- p myList.begin()
- for( p ! myList.end() p) p p 100
- p myList.begin()
- cout ltlt \n\n
- for( p ! myList.end() p) cout ltlt p ltlt
initialise the values
initialise the values
add 100 to elements
35A common mistake with End
- As we have seen end() and begin() are extremely
useful when handling these containers. - But, a common mistake occurs with the use of end
it does not point to the last element. - Rather it points to the element after the last
element. Hence the last element in a container is
given by - myList.end() - 1.
- This may seem a bit odd at first, but it is
designed to help us add new elements to the end
of your container.
36pushing and shoving
- It is important to think about whether you want
your most recent elements at the front or back of
a list. - Do you want to use push_front() or push_back()?
- It is often vital to make the right choice as it
can quite significantly change the efficiency of
your program -do you want your most recent
additions more readily accessible or your oldest? - Remember too that the insert() method can put an
element anywhere in the list.
37Sorting
- Forget your Bubblesorts these containers have
methods for organising the data. You can use the
sort() member function to sort a list - int main()
- listltintgt myList
-
- for(int i0 ilt10 i) myList.push_back(rand())
- myList.sort()
- listltintgtiterator p myList.begin()
- while( p!myList.end() ) cout ltlt p ltlt endl
384. Maps
- Maps are quite different from vectors and lists
they are an example of an Associative container. - In this structure unique keys are mapped with
values. Once stored the values can then be
retrieved by using the key. - map ltkey_type, value_typegt name
- In a map only unique keys are allowed (To use
nonunique keys you would have to setup another
associtaive container called a multi-map.)
39Pairs
- Inside the map itself we have these key-value
pairs, and these are stored as objects of type
pair - template ltclass Ktype, class Vtypegt struct pair
- typedef Ktype first_type
- typedef Vtype second_type
- Ktype first
- Vtype second
- pair()
- pair(const Ktype k, const Vtype v)
- templateltclass A, class Bgt pair(constltA, Bgt ob)
-
in the STL a pair is a struct template
3 ways of setting up the pair
40Adding Pairs to the Map
- When we are constructing a map we need these
pairs to fill it with. The syntax for this is as
follows - map ltint, stringgt m
- m.insert(pairltint, stringgt(1,Beckhams left
foot)) - You can also can also construct a pair using the
make_pair() function. The advantage of this is
that you dont need to specify the types its
automatically worked out for you by the compiler - m.insert( make_pair ( 2,Dirty argies) )
41Map Functions
size() - returns the no. of elements in the
map insert() - inserts a pair into the
map begin() - returns an iterator to the
start of the map end() - returns an
iterator to the end of the map clear() -
removes all elements from the map find() -
Returns an iterator to the specified
key count() - Returns the no. of time a key
occurs
- You can also use subcripting returns a
reference to the elemnt specified by i. If the
element doesnt exist it is inserted.
42Sorting through a Map find()
- int main()
- map ltchar, intgt m
-
- for(int i0 ilt26 i0)
- m.insert( make_pair( pair ltchar,intgt (Ai,
65i) ) - / Or m.insert( make_pair( pair ltchar,intgt
(Ai,Ai) / - char ch
- cout ltlt Enter a key
- cin gtgt ch
- map ltchar, intgtiterator p
- p m.find(ch)
- cout ltlt The ASCII value of
- cout ltlt p-gtfirst ltlt is ltlt p-gtsecond
find locates the key we are looking for
now we use the iterator to access the first and
second (key and value) properties
43Exercise of the day
- Write a function that reads an undefined number
of person data from standard input and prints
them out sorted on age. - Transform your function into a template such that
it can read any kind of data, and sort it on any
field.