Title: Computing Fundamentals with C
1C and Object-Oriented Programming Vectors
2Vectors
- Goals
- Construct vector objects that can store
collections of like objects. e.g. one vector
can store many numbers - Implement algorithms to process a collection of
objects. e.g. display all elements, find
min/max - Use the sequential search algorithm to locate a
specific element in a vector. - Pass vector objects to functions.
- Exercises
- Programming Projects
3Second Part of Chapter 10
- Part II
- Sort vector elements into ascending or descending
order. - Understand the binary search algorithm.
- Implement a container class with a vector data
member PREREQUISITE Chapter 6 - Exercises
- Programming Projects
- There are two sets of exercises and programming
projects
4The Standard C vector Class
- Some objects store precisely one value
- a double store one number
- an int stores one integer
- Other objects store more than one (possibly
dissimilar) values, for example - bankAccount objects store a string and a double
- What does a string object store?
- not sure
5Recall string objects
- Any string object stores a collection of
characters (more than one value) - individual characters are referenced with
- cout ltlt myName0 // reference the 1st char
- This chapter introduces vector objects which
- stores a collection of similar objects.
- Individual objects are accessed through
subscripts
6vectors are generic
- This code declares a vector named x
- vector ltdoublegt x( 100, 0.0 )
- x0 90.5
- x1 77.34
- that has the capacity to store 100 numbers
- the first two elements store 90.5 and 77.34
- the other 98 elements are 0.0 the 2nd
constructor argument - We can have a vector of almost any class of
objects the default constructor is used here - vector ltalmostAnyClassgt x( 100 )
7vectors are...
- A vector is homogeneous because all objects
stored under one vector name must be of the same
class. - vectors may be sized (at compile-time) or
dynamically sized (at runtime) - we can set the capacity of a vector at runtime
- cout ltlt "Number of students?"
- cin gtgt n
- vector ltstudentgt university(n)
- // default constructor called for n elements
8General form of vector construction
- vector ltclassgt identifier ( capacity,
initial-value ) - class specifies the class of objects stored in
the vector object. - identifier is the name of the vector object
- capacity is an integer expression specifying the
maximum number of objects that can be stored - initial-value is the value that every element
will be set to. The initial value is optional - If the initial-value is omitted, the default
constructor initializes every object in the
vector - Suggestion if class is int or double, specify an
initial-value
9Example Constructions
- A vector that stores up to 8 numbers, which are
all initialized to 0.0 - vector ltdoublegt x(8, 0.0)
- A vector that stores 500 string objects
- vector ltstringgt name(500)
- A vector that store 1,000 integers, which are all
initialized to -1) - vector ltintgt test(1000, -1)
- A vector that stores up to 100 bankAccounts
- vector ltbankAccountgt customer(100)
10Accessing Individual Elements in the Collection
- Individual array elements are referenced through
subscripts of this form - vector-name int-expression
- int-expression is an integer that should be in
the range of 0..capacity-1. - Examples
- x0 // Pronounced x sub 0
- name5 // Pronounced name sub 5
- test99 // Pronounced test sub 99
- customer12 // Pronounced customer sub 12
11Assignment and input operations work on
individual vector elements
- include ltvectorgt // for the standard vector
class - include ltiostreamgt
- using namespace std
- int main()
- int n 5
- vector ltintgt x(n, 0)
- x0 1 // Assume input of
- cout ltlt "Enter two integers " // 2 5
- cin gtgt x1 gtgt x2
- x3 x0 x2
- x4 x3 - 1
- for(int j 0 j lt n j) // LOOP OUTPUT?
-
- cout ltlt xj ltlt endl
-
- return 0
12The vector after modifying its state
13Processing the first n Elements of a vector
- The need often arises to access all mean-ingful
elements e.g. sum the first n elements in test - vector ltdoublegt test(100, -99.9)
- test0 64
- test1 82
- // assume 21 additional assignments
- test23 97
- int n 24
- double sum 0.0
- for(int j 0 j lt n j)
-
- sum testj
-
14Processing the first n elements of a vector
- A vector often has capacity larger than need be
- The previous example only used the first 24 of a
potential 100 elements. - The textbook often uses n to represent the number
of initialized and meaningful elements - The previous loop did not add x24 nor x25,
nor x99 all of which were -99.9 - vectors can be sized at runtime and even resized
later
15vector processing in this text book
- Example vector procesing you will see
- displaying some or all vector elements
- finding the sum, or average, or highest of all
vector elements - searching for a given value in the vector
- arranging elements in a certain order
- ordering elements from largest to smallest
- or alphabetizing a vector of strings from
smallest to largest
16Out of Range Subscripts
- Most vector classes don't care if you use
subscripts that are out of range - vector ltstringgt name(1000)
- name-1 "Subscript too low"
- name 0 "This should be the first name"
- name999 "This is the last good subscript"
- name1000 "Subscript too high"
- These other vector classes let you crash your
computer instead! segmentation or general
protection faults
17With MSVC 5.0 in Windows 95
- The standard vector class distributed with this
Microsoft's Compiler also gracefully terminates
the program with this
18Range Checking
- Recommendation use the vector class from this
textbooks disk - copy vector into your working folder
- including it this way works on some systems
- include "vector" // for a safe vector class
- You may have to change your include path settings
Optional Demo rangerr.cpp See if you can get the
safe vector
19vectorcapacity and vectorresize
- The the proper capacity of a vector is usually an
issue. - There are two useful functions to help
- int vectorcapacity()
- void vectorresize(int newSize)
20vectorcapacity and vectorresize
- include ltvectorgt // for the standard vector
class - using namespace std
- int main()
-
- vector ltintgt v1 // v1 cannot store any
elements - vector ltintgt v2(5)
- cout ltlt "v1 can hold " ltlt v1.capacity() ltlt
endl - cout ltlt "v2 can hold " ltlt v2.capacity() ltlt
endl - v1.resize(22)
- cout ltlt "v1 can now hold " ltlt v1.capacity() ltlt
endl -
- return 0
-
- Output
- v1 can hold 0
- v2 can hold 5
- v1 can now hold 22
21What happens during a resize message?
- When a vector is resized this book's safe vector
- and the new size is bigger than the old size
- the existing elements are intact
- and the new size is smaller than the old size
- the elements in the highest locations are
truncated
22Sequential Search
- We often need to search for data stored in an
vector (a phone number, an inventory item, an
airline reservation, a bank customer). - We will simplify the search algorithm by
searching only for strings. - Imagine however that the vector may be a
collection of bankAccounts, students, inventory,
sales, employees, or reservations.
23Sequential search algorithm
- There are many searching algorithms.
- We will study the sequential search algorithm
with a simple collection of strings. - Here is the first cut at the algorithm
- Initialize a vector of strings (call it
myFriends) - Get the name to search for (call it searchName)
- Try to find searchName
- Report on success or failure of search
24The array being searched
- We'll use this data in our searches
- vector ltstringgt myFriends(10)
- int n 5
- myFriends0 "DEBBIE"
- myFriends1 "JOEY"
- myFriends2 "BOBBIE"
- myFriends3 "SUSIE"
- myFriends4 "MIKEY"
- Note We often have unused elements in a vector.
For example, we could add 5 more strings to the
collection named myFriends.
25The Possibilities?
- searchName is in the vector
- searchName is not in the vector
- Now write the code that stores the index
(subscript) of searchName in myFriends - string searchName
- cout ltlt "Enter name to search for "
- cin gtgt searchName
- Dialogue
- Enter name to search for BOBBIE
26Sequential Search
- // assert searchName is in myFriends
- // --if it is not, watch out!
- // Search for searchName starting at myFriends0
- int subscript 0
-
- while(searchName ! myFriendssubscript)
- // assert searchName has not yet been found
- subscript // compare to next vector element
-
27Example search for "BOBBIE"
28Report success or failure
- // Report success or failure (see changes below)
- if(subscript lt n)
- cout ltlt myFriendssubscript ltlt " found"
- else
- cout ltlt searchName ltlt " not found"
- Question What would happen if searchName was not
amongst myFriends ?
29What if searchName isn't there?
30Self Help Exercise
- Rewrite the sequential search algorithm so it
works even if searchName is not in the vector
myFriends - int subscript 0
- while( ____________________________
- ____________________________ )
-
- subscript
-
31Sending messages to objects in a vector
- General form for sending a message to an
individual object in a vector - vector-name subscript . message
- Examples
- vector ltstringgt name(1000)
- vector ltbankAccountgt acct(10000)
- name3 "Any string"
- int n( name3.length() )
- acct99 bankAccount("Westphall", 345.67)
- acct99.withdraw(100.00)
- cout ltlt acct99.balance() ltlt endl
32Initializing a vector of Objects with File Input
- A vector is often initialized with file input.
- For example, might need to initialize a data base
of bank customers with this file input - Cust0 0.00
- AnyName 111.11
- Austen 222.22
- Chelsea 333.33
- Kieran 444.44
- Cust5 555.55
- ... Note Seven lines are omitted ...
- Cust11 1111.11
33Some preliminaries
- // Initialize a vector of bankAccounts through
file input - include ltfstreamgt // for class ifstream
- include ltiostreamgt // for cout
- include ltvectorgt // for the standard vector
class - include "baccount" // for class bankAccount
- int main()
-
- ifstream inFile( "bank.dat" )
- if( ! inFile )
-
- cout ltlt "Error file 'bank.dat' not found"
ltlt endl -
- else
-
34Reading until end of file
- vector ltbankAccountgt account( 20 )
- string name
- double balance 0.0
- int n 0
- int j 0
- while( ( inFile gtgt name gtgt balance )
- ( n lt account.capacity() ) )
-
- // Create and store a new bankAccount in next
location - account n bankAccount( name, balance )
- // Increase initialized accounts and
- // get ready to locate the next new
bankAccount - n
-
- // end else
Optional Demo file2vec.cpp
35vector argument/parameter associations by
example
- void foo( vector lt bankAccount gt acct )
- // VALUE parameter (should not be used with
vectors) - // all elements of acct are copied
- // after allocating the additional memory
-
- void foo( vector lt bankAccount gt acct )
- // REFERENCE parameter (allows changes to
argument) - // Only a pointer the acct is copied.
- // A change to acct changes the argument
-
-
- void foo( const vectorltbankAccountgt acct )
- // CONST REFERENCE parameter (for
efficiency and safety) - // Only a reference to the acct is copied (4
bytes) - // A change to acct does NOT change the
argument -
36Example vector pass vector by reference
- void init(vector lt int gt x, int n)
-
- n 4
- x.resize(n)
- x0 0
- x1 11
- x2 22
- x3 33
-
- int main()
-
- vector ltintgt test
- int n 0
- init(test, n)
- // aVector has a capacity of 4
37Sorting
- Sorting the process of arranging vector
elements into ascending or descending order - Ascending (where x is a vector object)
- x0 lt x1 lt x2 lt ... lt xn-2 lt
xn-1 - Descending
- x0 gt x1 gt x2 gt ... gt xn-2 gt
xn-1 - Here's the data used in the next few slides
38Swap largest with the first
- // Swap the largest element with the first
- top 0
- largestIndex top
- for j ranging from top1 through n - 1
-
- if test j gt test largestIndex then
- largestIndex j
-
- // Question What is largestIndex now __________?
- swap test largestIndex with test top
39Selection sort algorithm
- Now we can sort the entire vector by changing top
from 0 to n-2 with this loop. - for (top 0 top lt n-1 top)
- for each subvector, get the largest on top
- The top moves down one vector position each time
the largest is placed on top. - Eventually, we get a sorted vector.
40Trace selection sort
41Binary Search
- We'll see that binary search can be a more
efficient algorithm for searching - It works only on sorted arrays like this
- Compare the element in the middle
- if that's the target, quit and report success
- if the key is smaller, search the array to the
left - otherwise search the array to the right
- This process repeats until we find the target or
there is nothing left to search
42Binary Search Harry
Data reference pass 1 pass 2
Bob
a0 a1 a2 a3 a4 a5 a6 a7 a8
low mid high
low mid high
Carl
Debbie
Evan
Froggie
Gene
Harry
Igor
Judy
43How fast is Binary Search?
- Best case 1 comparison
- Worst case when the target is not there
- At each pass, the live portion of the array
(where we need to search) is narrowed to half the
previous size. - The series proceeds like this
- n , n/2, n/4, n/8, ...
- Each term in the series represents one
comparison. How long does it take to get to 1? - This will be the number of comparisons
44Comparing O(n) sequential search to O(log n)
binary search
Rates of growth and logarithmic functions
45Graph Illustrating Relative Growth
f(n)
n
log n
n
46Defective Binary Search
- Binary search sounds simple, but it's tricky
- int binarySearch(const vector ltintgt a,
- int n, int target)
- // pre array a is sorted from a0 to an-1
- int first 0, last n-1, int mid
- while(first lt last)
-
- mid (firstlast)/2
- if(target amid)
- return mid // found target
- else if(target lt amid)
- last mid // must be that target gt
amid - else
- first mid // must be that target gt
amid -
- return -1 // use -1 to indicate item
not found -
47Search for "Duckie"
Data pass 1 pass 2
pass 3 pass 4...
Bob
a0 a1 a2 a3 a4
low mid high
low mid high
low mid high
low... mid... high...
Carl
Debbie
Evan
Froggie
How do we fix this defective binary search ?
_____?
Optional Demo binserch.cpp