32
Lesson 16 Ricardo Salazar, Pic 10A

Ricardo Salazar, Pic 10Arsalazar/winter2020/lessons/les… · (6.1) Vectors vector allow us to store a list of variables/objects that belong to the same class. To use vectors we need

  • Upload
    others

  • View
    0

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Ricardo Salazar, Pic 10Arsalazar/winter2020/lessons/les… · (6.1) Vectors vector allow us to store a list of variables/objects that belong to the same class. To use vectors we need

Lesson 16Ricardo Salazar, Pic 10A

Page 2: Ricardo Salazar, Pic 10Arsalazar/winter2020/lessons/les… · (6.1) Vectors vector allow us to store a list of variables/objects that belong to the same class. To use vectors we need

Storing data in lists● Suppose we want to keep track of a list of 4

numbers:○ E.g: 10, 2015, 0, -1

■ We could create 4 int variables.int value1, value2, value3, value4;

● But this does not scale well. What if we have a list of 10 numbers? What if we have 2018?

● Now imagine a huge database… ● … or an 8 megapixel image!● In C++ a list of numbers can be stored in a single

variable.● It is a nice feature. Without it programming would

be very hard.

Page 3: Ricardo Salazar, Pic 10Arsalazar/winter2020/lessons/les… · (6.1) Vectors vector allow us to store a list of variables/objects that belong to the same class. To use vectors we need

Arrays and Vectors● There are at least two options for storing data in lists:

○ arrays, and ○ vectors.

● Arrays are old-fashioned and simple.○ They are built-in primitive data types in C++ … ○ … which means: No helper functions.

● Vectors are more recent. Think of them as fancier arrays with some special features.○ They are defined in the <vector> library, and○ they come with member functions.

● The usage for both types is very similar... ○ but there are some subtle differences.

Page 4: Ricardo Salazar, Pic 10Arsalazar/winter2020/lessons/les… · (6.1) Vectors vector allow us to store a list of variables/objects that belong to the same class. To use vectors we need

(6.1) Vectors● vector allow us to store a list of variables/objects

that belong to the same class.○ To use vectors we need to statement: #include <vector>.

● Syntax:vector<dataType> variableName(size);

○ where size is a nonnegative integer.○ If omitted, it defaults to 0.

● To create a vector of 10 integers writevector<int> myVector(10);

● Any data type can be used. Even classes…vector<string> listOfWords(2018);vector<BikeFrame> sieteOnceTeamBikes(9);

Page 5: Ricardo Salazar, Pic 10Arsalazar/winter2020/lessons/les… · (6.1) Vectors vector allow us to store a list of variables/objects that belong to the same class. To use vectors we need

(6.2) Accessing vectors● To access the element of a vector at position i, use

the brackets notation [i]. For example, the code:vector<int> myVector(10);myVector[7] = 3.14;

○ Stores 3.14 in the eighth position of myVector.● Vector indices run from 0 to size-1.

○ Just like strings… ○ … because a string is a vector of char elements.

● Similarly: ○ string comes with length(), and ○ vector comes equipped with size().E.g: for (int i=0 ; i < myVector.size() ; i++ )

cout << myVector[i] << endl; // Displays all elements of myVector

Page 6: Ricardo Salazar, Pic 10Arsalazar/winter2020/lessons/les… · (6.1) Vectors vector allow us to store a list of variables/objects that belong to the same class. To use vectors we need

ExamplesStore the first 50 odd integers:

vector<int> odds(50);for (int i=0; i<50 ; i++) odds[i] = 2*i+1;

Read 99 doubles and compute the average:

vector<double> v(99);double sum = 0.0;for (int i=0; i<v.size(); i++){ cin >> v[i]; sum += v[i];}cout << "Average: " << sum/v.size() << endl;

Read 10 words, store them, and find the longest one.

vector<string> w(10);string longest = "";

for (int i=0; i<w.size(); i++){ cout << "Word " << i+1 << ": "; cin >> w[i];

int n = w[i].length(); int m = longest.length(); if ( n > m ) longest = w[i]; }cout << "Longest word : " << longest << endl;

Page 7: Ricardo Salazar, Pic 10Arsalazar/winter2020/lessons/les… · (6.1) Vectors vector allow us to store a list of variables/objects that belong to the same class. To use vectors we need

● Vectors can grow or shrink.● To add one more value to the back end of a vector

use the member function call push_back(value).vector<double> myVector(4);// read the numbers 3, 3.1, 3.14, 0.1myVector.push_back(4.13);

push_back and pop_back

3 3.1 3.14 0.1

3 3.1 3.14 0.1 4.133 3.1 3.14 0.1

● To remove the last element of the vector, call the member function pop_back().

myVector.pop_back();

3 3.1 3.14 0.1 4.13

size increases to 5

size decreases to 4

Page 8: Ricardo Salazar, Pic 10Arsalazar/winter2020/lessons/les… · (6.1) Vectors vector allow us to store a list of variables/objects that belong to the same class. To use vectors we need

Vectors are dynamic● Suppose we are to read a list of doubles from the

user but we don't know how many will be entered.● We can start with an empty vector and push_back

numbers until cin fails.vector<double> manyNumbers; // size defaults to 0double newEntry;while ( cin >> newEntry ) manyNumbers.push_back(newEntry);

● manyNumbers now stores all entered numbers.● If we want to know how many there are, we can call

the size member function… cout << " You entered : " << manyNumbers.size() << " numbers." << endl;

Page 9: Ricardo Salazar, Pic 10Arsalazar/winter2020/lessons/les… · (6.1) Vectors vector allow us to store a list of variables/objects that belong to the same class. To use vectors we need

Resizing vectors● The resize member function resets the vector to a

given newSize.vector<int> v(10); // v starts with 10 elementsv.resize(20); // Now v has 20 elements

● If ○ newSize > oldSize, default elements are added.○ newSize < oldSize, elements off the back are deleted.

v.resize(5); // Only the first 5 elements are kept

● If we want to start over and go back to an empty vector we can resize it back to 0.

v.resize(0); //Now v is an empty vector.

Page 10: Ricardo Salazar, Pic 10Arsalazar/winter2020/lessons/les… · (6.1) Vectors vector allow us to store a list of variables/objects that belong to the same class. To use vectors we need

Example (card hands) ● In card games, each player has a set of cards (hand).● Let us build a Card class.

○ Let us have the constructor draw a random card.○ Let us also code two 'getters' to retrieve the rank and suit.○ I'll give you a few minutes…

● Now let us build a Hand class using our Card class.class Hand { public: Hand(); . . . private: // The list of cards. vector<Card> cards;};

○ What functions should this class have?

Page 11: Ricardo Salazar, Pic 10Arsalazar/winter2020/lessons/les… · (6.1) Vectors vector allow us to store a list of variables/objects that belong to the same class. To use vectors we need

The Hand class● Every time the player draws a card, we should add it

to the vector cards in our hand:void Hand::drawCard() { Card newCard; //Creates a random card. cards.push_back(newCard); return;}

● When a round of play is over, the player turns in all the cards:

void Hand::resetHand() { cards.resize(0); return;}

Page 12: Ricardo Salazar, Pic 10Arsalazar/winter2020/lessons/les… · (6.1) Vectors vector allow us to store a list of variables/objects that belong to the same class. To use vectors we need

Casino revisited (blackjack a.k.a. 21)

● In Blackjack a player plays against the dealer.● Whoever gets the sum of their card values closest to

21 without going over, wins.● The dealer draws cards until the sum is bigger or

equal to 17.● Assuming we have a sum() member function in our

Hand class that adds up the card values…Hand dealer;while ( dealer.sum() < 17 ) dealer.drawCard();

● Once the round is over the dealer turns in the cards.dealer.resetHand();

Page 13: Ricardo Salazar, Pic 10Arsalazar/winter2020/lessons/les… · (6.1) Vectors vector allow us to store a list of variables/objects that belong to the same class. To use vectors we need

(6.3) Vectors in functions● To pass a vector to a function use

returnType functionName(vector<type> vectorName){

● We do have to tell the function what type of data the vector holds.

● But it is not necessary to tell the function the size of the vector. ○ It is available through the size() function.

void print( vector<int> v ) { for ( int i=0 ; i<v.size() ; i++ ) cout << v[i] << " "; return;}

Page 14: Ricardo Salazar, Pic 10Arsalazar/winter2020/lessons/les… · (6.1) Vectors vector allow us to store a list of variables/objects that belong to the same class. To use vectors we need

Vectors in functions (cont)● A function CAN return a vector.

○ Ex: Extract the int sub-vector between positions s and f of a given vector.

vector<int> extract(vector<int> v, int s, int f){ vector<int> sub( f - s + 1 ); // start empty for ( int i=s ; i<=f; i++ ) sub[i-s] = v[i]; // push_back instead return sub;}

○ What would be the result if instead of sub[i-s] = v[i] we tried v[i-s] = v[i] and changed the return type to void?

-1 3 7 2 -4 5 8 7 2 -4

s f

Page 15: Ricardo Salazar, Pic 10Arsalazar/winter2020/lessons/les… · (6.1) Vectors vector allow us to store a list of variables/objects that belong to the same class. To use vectors we need

Example● Functions CAN return vectors. Did I say so already?

○ Ex: Read a list of numbers from the user and put them in a vector. Stop when they do not enter a number.

○ Recall that (cin >> x) is interpreted as true if it read x successfully and is interpreted as false otherwise.

1.23 12 -3.1416 4.321 Chavo 1.23 12 -3.14 16 4.321

vector<double> read() { vector<double> numbers; int newEntry; while ( cin >> newEntry ) numbers.push_back(entry); return numbers;}

Page 16: Ricardo Salazar, Pic 10Arsalazar/winter2020/lessons/les… · (6.1) Vectors vector allow us to store a list of variables/objects that belong to the same class. To use vectors we need

Example: appending vectors(c.f. overloading of + in string)

○ Ex: Write a function which appends vector v2 (int) onto the back end of vector v1.

void append(vector<double>& v1, vector<double> v2){ for ( int i=0 ; i<v2.size() ; i++ ) v1.push_back( v2[i] ); return;}

○ Why is v1 passed by reference and v2 by value?○ What would change if we pass v2 by reference?

v2

1 0

resulting vector v1

6 3 -8 4 1 0

v1 by reference

6 3 -8 4

Page 17: Ricardo Salazar, Pic 10Arsalazar/winter2020/lessons/les… · (6.1) Vectors vector allow us to store a list of variables/objects that belong to the same class. To use vectors we need

Vector member functions● Class: vector<data_t>

data_t could be int, double, string, Card, etc.

Member function Description

vector(int n) Constructs a vector with n elements.

int size() Returns current size of vector

void push_back(data_t d) inserts d at the back of the vector

void pop_back() Removes last element of the vector.

void resize(int n) Resizes vector to size n. If n is less than the old size, elements at the back are deleted.

Page 18: Ricardo Salazar, Pic 10Arsalazar/winter2020/lessons/les… · (6.1) Vectors vector allow us to store a list of variables/objects that belong to the same class. To use vectors we need

Strings as vectors● A string is a vector of char elements

string name = "Ramon";name[0] = 'J';cout << name; // Prints Jamon (Ham, yummy!)

● A string variable can use vector member functions.name.push_back('s'); //Adds one char to the end.

● Say you had to replace every s in a string with an f.○ You could extract the single letter 's' with substring,

then erase it and finally insert the 'f'.○ Or you could use vector notation

for ( int i=0 ; i < myString.length() ; i++ ) { if ( myString[i] == 's' ) myString[i] = 'f';}

Page 19: Ricardo Salazar, Pic 10Arsalazar/winter2020/lessons/les… · (6.1) Vectors vector allow us to store a list of variables/objects that belong to the same class. To use vectors we need

Conserving memory● Every time a variable is passed by value to a

function, a local copy of the variable is created.○ If a vector storing one million integers is passed by value,

a new vector of size one million is created.○ This eats up memory and can crash your program.

● In these cases consider passing a vector by reference.○ But remember that changes will be recorded

■ You can either be super careful.■ Or you can 'add insurance' to prevent accidental changes.

● To 'add insurance', use the const modifiervoid myFunction( const vector<int>& myVector )

Page 20: Ricardo Salazar, Pic 10Arsalazar/winter2020/lessons/les… · (6.1) Vectors vector allow us to store a list of variables/objects that belong to the same class. To use vectors we need

Example: searching a list○ Ex: Search through a vector for a specific value and return the

position of the first occurrence.

int findValue(const vector<int>& v, int x){ int i=0; while( i<v.size() && v[i] != x ) i++; return i;}

○ What does this return if x was not in the vector v?

v by reference with const to prevent changes

6 -5 13 7 0

0 1 2 3 4

int pos = findValue( v , 7 ); // pos =

returns 3

3

Page 21: Ricardo Salazar, Pic 10Arsalazar/winter2020/lessons/les… · (6.1) Vectors vector allow us to store a list of variables/objects that belong to the same class. To use vectors we need

Example: erasing an element○ Ex: Erase from a vector v (int) the element stored at a given

position.

void erase(vector<double>& v, int pos) { if ( pos>=0 && pos<v.size() ){ for (int i=pos ; i < v.size() - 1 ; i++) v[i] = v[i+1]; v.pop_back(); }}

○ What happens if pos equals v.size()-1?

v by reference to record changes

6 -5 13 7 0

0 1 2 3 4

erase(v,2); v

6 -5 7 0

0 1 2 3

Page 22: Ricardo Salazar, Pic 10Arsalazar/winter2020/lessons/les… · (6.1) Vectors vector allow us to store a list of variables/objects that belong to the same class. To use vectors we need

Example: inserting an element○ Ex Insert a double x before a given position in a double vector

v: insert(v,2,x);

You do it...

Page 23: Ricardo Salazar, Pic 10Arsalazar/winter2020/lessons/les… · (6.1) Vectors vector allow us to store a list of variables/objects that belong to the same class. To use vectors we need

(6.4) Parallel vectors

Say we want to create a phonebook app.● We would need to keep track of different individual data

types like○ name (string name)○ phone number (int phone)○ friend score!!! (int score)

● Friendships are dynamic… ● We need resizable containers. ● We can use parallel vectors.

name

Ramon

Chavo

Quico

Chilindrina

Popis

phone

1234567

8901234

2223344

9876543

5555554

0

1

2

3

4

score

8

10

5

7

3

vector<string> name(5);vector<int> phone(5);vector<int> score(5);

● But it is hard work keeping track of 3 separate vectors.

Page 24: Ricardo Salazar, Pic 10Arsalazar/winter2020/lessons/les… · (6.1) Vectors vector allow us to store a list of variables/objects that belong to the same class. To use vectors we need

Parallel vectors (cont)

But… ● it is hard work keeping track of

3 separate vectors.

phone

1234567

8901234

2223344

9876543

5555554

// Popis is no longer our friend. // Remove record using functions// erase(vector<T>& ,int )

name

Ramon

Chavo

Popis

Chilindrina

Quico

score

8

10

3

7

5

0

1

2

3

4

name

Ramon

Chavo

Chilindrina

Quico

phone

1234567

8901234

9876543

5555554

score

8

10

3

7

5

erase(name,2);erase(phone,2);

// What if we make mistakes?// erase(score,2);

Page 25: Ricardo Salazar, Pic 10Arsalazar/winter2020/lessons/les… · (6.1) Vectors vector allow us to store a list of variables/objects that belong to the same class. To use vectors we need

(6.4) Parallel vectors● A better solution is to create a class Friend with

private variables name, phone and score.● Then create just one vector<Friends> object.class Friend { public: . . . private: string name; int phone; int score;}. . . int main(){ vector<Friend> myFriends(5); . . . erase(myFriends,3); . . .}

Friend

Friend

Friend

Friend

Page 26: Ricardo Salazar, Pic 10Arsalazar/winter2020/lessons/les… · (6.1) Vectors vector allow us to store a list of variables/objects that belong to the same class. To use vectors we need

Sorting a vector (integers)● The <algorithm> library contains a function that is

capable of sorting a vector or an array.● The function is called sort.

○ A typical call has the form:sort( iteratorToBeginningOfVector , iteratorToEndOfVector );

○ We will explain what iterators are at a later time…

● For now we only need to know that○ the vector member function begin() returns an iterator to

the beginning of the vector,○ and that the vector member function end() returns an

iterator to the end of the vector.

Page 27: Ricardo Salazar, Pic 10Arsalazar/winter2020/lessons/les… · (6.1) Vectors vector allow us to store a list of variables/objects that belong to the same class. To use vectors we need

Sorting (cont)The code below sorts and prints a vector of integers:

#include <iostream>#include <vector>#include <algorithm>using namespace std;

int main(){ vector<int> v(4); v[0]=25; v[1]=2; v[2]=13; v[3]=9;

sort( v.begin() , v.end() ); for ( int i=0 ; i < v.size() ; i++ ) cout << v[i] << " "; cout << endl; return 0;}

Output: 2 9 13 25

Page 28: Ricardo Salazar, Pic 10Arsalazar/winter2020/lessons/les… · (6.1) Vectors vector allow us to store a list of variables/objects that belong to the same class. To use vectors we need

Sorting a vector (other types)● We can also sort double and string…

○ It looks a little strange because strings are sorted in lexicographic order.

● Can we sort Point objects?○ No. The compiler doesn’t know how to compare points.

● Can we sort Product objects?○ Yes. Recall we have the member function:

Product::operator < (Product b);

1.23 0.21 34.1 -10 17.2 -10 0.21 1.23 17.2 34.1sort

chavo ramon 8 led ovahc CHAVO

8 led ovahc CHAVO chavo ramonsort

Page 29: Ricardo Salazar, Pic 10Arsalazar/winter2020/lessons/les… · (6.1) Vectors vector allow us to store a list of variables/objects that belong to the same class. To use vectors we need

Sorting 'naipes' (cards)○ Ex: Create and sort a 13 cards out of a deck.

■ We need the operator <. Write the implementation. I'll wait!

vector<Card> deck(13);for ( int i=0 ; i<deck.size() ; i++ ) { Card newCard; deck[i] = newCard;}

sort( deck.begin() , deck.end() );for ( int i=0 ; i<deck.size() ; i++ ) { cout << deck[i].get_rank() << " of " << deck[i].get_suit() << endl;}

○ Note this sorts on the rank, but the suits are in random order.

Page 30: Ricardo Salazar, Pic 10Arsalazar/winter2020/lessons/les… · (6.1) Vectors vector allow us to store a list of variables/objects that belong to the same class. To use vectors we need

Everyday I'm shuffling… Ex: Shuffle a deck of 52 cards.

○ We want to call a function shuffle like this:

vector<Card> deck(52);shuffle(deck);

○ Idea: Pick 2 random cards from the deck and swap their positions. ■ Repeat many times.

○ Let’s do 2018 swaps.

void shuffle(vector<Card>& v){

Card temp; for (int i=1; i<=2016; i++){ int pos1 = rand()%52; int pos2 = rand()%52;

temp = v[pos1]; v[pos1] = v[pos2]; v[pos2] = temp; } return;}

Page 31: Ricardo Salazar, Pic 10Arsalazar/winter2020/lessons/les… · (6.1) Vectors vector allow us to store a list of variables/objects that belong to the same class. To use vectors we need

Quick summary● A vector is a class that can store data in a list.● We set the type and initial size in the declaration.

vector<string> listOfWords(7);vector<int> myVector(314);

● Request the size of a vector with .size()int totalWords = listOfwords.size();

● To access an element use brackets: []● Indices start at 0.

listOfWords[0] = "hola"; cout << myVector[1] + myVector[2];

● Vectors are dynamic.listOfWords.resize(5); // First 5 elements survivelistOfWords.push_back("Ramon"); // Add "Ramon" to endlistOfWords.pop_back(); // Remove last element

Page 32: Ricardo Salazar, Pic 10Arsalazar/winter2020/lessons/les… · (6.1) Vectors vector allow us to store a list of variables/objects that belong to the same class. To use vectors we need

2D Vectors (tables or matrices)● Creating a 'table' is easy with arrays (more on this later).

int myMatrix[2][4]; // Creates an empty 2x4 matrix

● Creating it with vectors is not so easy.○ Method 1: Create a vector of size rows*cols and keep track of

the rows and columns yourself… /* Creates a "Matrix" with 8 elements */vector<int> myFakeMatrix(8);

○ Method 2: Create a vector of vectors./* Creates an empty 2x4 matrix */vector< vector<int> > VectorOfRows(2); vector<int> row(4);for ( int i=0 ; i<VectorOfRows.size() ; i++ ) vectorOfRows[i] = row;

● For two dimensional data it's better to use arrays.