Download The vector class

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts

Array data structure wikipedia , lookup

Transcript
Introduction to STL and the vector
container class
CS342 Data Structures
Based on Ford & Topp
Intro to STL (Standard Template
Library) container classes


Data structure: a container of data that
supports insertion, deletion, and updating
operations on the stored data.
Classical data structures such as vector;
queue, deque, and priority queue; list,
stack; set and multiset, map and multimap
have been pre-programmed as template
classes and integrated into C++ as STL.
Categories of STL container classes
Sequence
containers
vector
Adapter
containers
stack
associative
containers
set and multiset
deque
queue
map and
multimap
list
priority-queue
Sequence containers: data elements stored in linear order.
Adapter container: contains another container (usually a sequence container) as
its underlying storage structure.
Associative container: stores elements by keys such as Id numbers.
Illustrations of STL sequence containers
Sequence Container
Position 0
Position 1
Position 2
Position 3
Position 4
Linked list
next
next
next
front
next
rear
Vertor
v[0]
0
v[1]
1
v[2]
2
. . .
v[n-1]
n-1
room to grow
Illustrations of STL adapter containers
(using sequence containers as the storage)
top
A
Push A
A
B
A
Push B
(a)
B
C
top
C
B
A
Push C
C
top
B
A
Pop C
Insert
E
A
rear
front
A
top
Pop B
(b)
B
D
B
top
C
Delete
D
E
Illustrations of STL associative
containers
Set A
5
Set B
1
Buick
BMW
Ford
Jaguar
Honda
Jeep
Index
Part#
Price
A29-468
D7B-916
4.95
Mirage
D7B-916
W91-A83
12.50
Calloway
W91-A83
A29-468
8.75
Martin
3
27
15
Vendor
A quick review of C++ arrays

An array is a fixed-size collection of values of the same data type.
arr[0]
0



arr[1]
arr[2]
1
2
...
arr[n-1]
n-1
An array is a container that stores the n (size) elements in a
contiguous block of memory. Once declared, n cannot be changed.
Array name is associated with the address of the array. So when an
array is passed to a function, the size (or the number of elements
that need to be processed) of the array must also be passed.
Directly assigning one array to another of same size and type are
not allows: arrayA = arrayB; // syntax error!
The vector container class characteristics


Similar to a one-dimensional array: use index for direct access.
Can dynamically grow and contract (remember size of an
conventional array cannot be changed once it is declared!)
v[0]
0

v[1]
1
v[2]
2
...
v[n-1]
room to grow
n-1
vector is a STL class, it contains many useful member functions
 size(), pushback(), back(), popback, resize(), empty(), etc.
A simple example
// Vector function writeVetor( )
template <typename T>
void writeVctor(const vector<T> &v )
{
int i, n = v.size( );
// size( ) is a member function
for (i = 0; i < n; i++)
cout << v[i] << '\t';
// identical to an array
cout << endl;
}
Examples of how vector objects are
declared and initialized
// without initialization
vector<int> v(5);
vector<string> s(10);
// with initialization
vector<char> line(80, 'A');
vector<time> t(5, time(12,30, 0));
// initialization from an array
int a[5] = {1, 2, 3, 4, 5};
vector<int> v(a, a + 5);
// vector of size 5 containing 0's
// size 10, each element contain null string
// 80 characters, each initialized to 'A'
// 5 elements with initial value 12:30:00
// array with initial values
// initial values copied from the array a
// notice a + 5 is the address just past the end
// of array a
// initialization without specifying the size, the initial size will be defaulted to 0
vector<double> dblv;
vector<string> s2;
Vector member function push_back( ) and
pop_back( )
v.size( ) = 4
11
22
33
44
0
1
2
3
v.push_back(55);
v.size( ) = 5
v.pop_back( );
v.size( ) = 4
11
22
33
44
0
1
2
3
11
22
33
44
55
0
1
2
3
4
The sizeof( ) operator and back( )
member function
char vowel[ ] = {'a'. 'e', 'i', 'o', 'u'};
int vowelSize = sizeof(vowel)/sizeof(char);
vector<char> v(vowel, vowel + vowelSize);
cout << v.back( );
v.push_back('w');
v.back( ) = 'y';
// output 'u'
// add 'w' to end of v
// change back from 'w' to 'y'
Example: start with an empty vector and build a list
with input (values of double type) from the user
vector<double> list;
// declares an empty list
double data;
cout << “Enter a list of real values: “;
cin >> data;
while(data != -99) {
list.push_back(data);
cin >> data;
}
Example: the pairing of back( )
and pop_back( )
int a[ ] = {1, 2, 3, 4, 5, 6};
int aSize = sizeof(a) / sizeof(int);
vector<int> v(a, a + aSize);
while(!v.empty( )) {
cout << v.back( ) << '\t';
v.pop.back( );
}
// output: 6 5 4 3 2
1
Resizing a vector with resize( )
member function
int a[ ] = {1, 2, 3, 4, 5};
int aSize = sizeof(a) / sizeof(int);
vector<int> v(a, a + aSize); // size = 5
v.resize(2 * aSize);
// size = 10, "fill" value is 0
v.resize(4);
// size = 4, data is lost
v.resize(10, 1);
// size = 10. fill value is 1
How is the vector class defined:
the vector class abstraction

The constructors
vector( );
// default constructor creates an empty vector.
vector(int n, const T& value = T( ));
/* creates a vector with n elements, each have the specified value. If
value is omitted, the elements are filled with the default value
for type T. Type T must have a default constructor, a nd the
default value of type T is specified by the notation T( ). */
vector(T *first, T *last);
/* initialize the vector using the address range [first, last).
The abstraction of the vector
class continued

The member functions or operations
T &back( );
// returns the value of the item at the rear of the
vector
// Pre-condition: the vector must contain at least one element.
const T &back( ); // const version of back( );
bool empty( ) const;// returns true if vector is empty, false otherwise
T &operator[ ](int i);
// allows element at index i to be retrieved or modified.
const T &operator[ ](int i); // const version of T &operator[ ](int i);
void push_back(const T &value); /* Post-condition: a new element is
added to the rear and the size of the vector is increased by 1. */
The abstraction of the vector
class continued

The member functions or operations (continued)
void pop_back( ); /* removes the item at the rear;
Precondition: the vector is not empty
Post condition: the size of the vector is decreased by 1.
*/
void resize(int n, const T & fill = T( )); /* modifies the
size of the vector; if the size is increased, new elements
with value fill are added to the rear of the vector. If the
value is decreased, the original values at the front are
retained. Post-condition: the vector has size n. */
int size( ) const; /* returns the number of elements in the
vector. */
A simple application: join two
vectors together
template <typename T>
void join(vector<T> &v1, const vector <T> &v2)
{
int i, sizev2 = v2.size( );
for (i = 0; i < sizev2; i++)
v1.push_back(v2[i]);
}
The insertion sort
Monroe
Start with Monroe
Insert Chin in location 0;
Monroe moves to location 1
Chin
Monroe
Processing Flores
Chin
Flores
Monroe
Insert Flores in location 1;
Monroe moves to location 2
Processing Stein
Chin
Flores
Monroe
Stein
Processing Chin
Processing Dare
Chin
Dare
Flores
Monroe
Element Stein is OK
Stein
Insert Dare at
location 1;
the tail of the list
shifts to the right
The insertion sort
//insertionSort():
// sort a vector of type T using insertion sort
template <typename T>
void insertionSort(vector<T>& v)
{
int i, j, n = v.size();
T temp;
// place v[i] into the sublist v[0] ... v[i-1], 1 <= i < n,
// so it is in the correct position
The insertion sort continued
for (i = 1; i < n; i++)
{ // index j scans down list from v[i] looking for
//correct position to locate target. assigns it to v[j]
j = i;
temp = v[i];
// locate insertion point by scanning downward as
// long as temp < v[j-1] and we have not
// encountered the beginning of the list
The insertion sort continued
while (j > 0 && temp < v[j-1])
{
// shift elements up list to make room for insertion
v[j] = v[j-1];
j--;
}
// the location is found; insert temp
v[j] = temp;
}
}
Running time of insertion sort





requires (n-1) passes
for pass i, the insertion occurs in the sublist v[0] to v[i-1]
and requires an average of i/2 comparisions. Thus, T(n) =
1 / 2 + 2/2 + … + (n-2)/2 + (n-1)/2 = n(n-1)/4 or the
running time is O(n2).
The best case occurs when the list is already in order, the
total number of comparson T(n) = n-1, leading to O(n)
running time.
The worst case occurs when the list is in descending order
and T(n) = n(n-1)/2 or O(n2) running time.
The insertion sort exhibits the best performance among
the quadratic sorting algorithms when the list is partially
ordered.
Another vector application: joining
three sorted sublists
// File: prg4_2.cpp
// the program generates 12 random integers in the range
// 100 to 999. add each number value to vector vSmall if
// value < 400, to vector vMedium if 400 <= value < 700
// and to vLarge if 700 <= value < 1000. apply the insertion
// sort to order each vector. use join() so that vSmall is
// the concatenation of the three vectors. sort the final list
// in vSmall by using the insertion sort. display the initial
// set of elements in each vector and the final sorted list
// by calling writeVector()
Another vector application: joining
three sorted sublists continued
#include <iostream>
#include <vector>
#include "d_random.h"
// for randomNumber
#include "d_sort.h"
// for insertionSort()
#include "d_util.h"
// for writeVector()
using namespace std;
// attach vB onto the end of vA
template <typename T>
void join (vector<T> &vA, const vector<T>& vB);
Another vector application: joining
three sorted sublists continued
int main()
{
// declare 3 integer vectors
vector<int> vSmall, vMedium, vLarge;
// use a random number generator
randomNumber rnd;
int i, value;
for (i = 0; i < 12; i++)
{
value = rnd.random(900) + 100;
if (value < 400)
vSmall.push_back(value);
else if (value < 700 )
vMedium.push_back(value);
else
vLarge.push_back(value);
}
Another vector application: joining three
sorted sublists continued
// sort the vector of integers in the range
// 100 <= n < 400 and output
insertionSort(vSmall);
cout << "Small: ";
writeVector(vSmall);
// sort the vector of integers in the range
// 400 <= n < 700 and output
insertionSort(vMedium);
cout << "Medium: ";
writeVector(vMedium);
Another vector application: joining
three sorted sublists continued
// sort the vector of integers in the range
// 700 <= n < 1000 and output
insertionSort(vLarge);
cout << "Large: ";
writeVector(vLarge);
// join vMedium onto the end of vSmall
join(vSmall, vMedium);
// join vLarge onto the end of the modified vSmall
join(vSmall, vLarge);
// output the new vector
cout << "Sorted: ";
writeVector(vSmall);
return 0;
}
Another vector application: joining
three sorted sublists continued
template <typename T>
void join (vector<T> &vA, const vector<T>& vB)
{
// capture the size of vB in sizeB
int i, sizeB = vB.size();
// use index i to access the elements of vB and push_back()
// to add the elements to the rear of vA
for (i = 0; i < sizeB; i++)
vA.push_back(vB[i]);
}
/*
Run:
Small: 176 213 269 287 357
Medium: 482 535 551 649 687
Large: 843 901
Sorted: 176 213 269 287 357 482 535 551 649 687 843 901
The matrix class


Because of its importance in science and
engineering applications, matrix class has been
included in the C++ STL.
Matrix is implemented as a vector of vectors:
vector<vector<T> > mat; /* the outer vector corresponds
to rows of the matrix, the elements in the inner vector of
type T correspond to the column entries for each vector
row. For example, mat[0] is the vector of column
entries corresponding to row 0, etc. Note that there
must be a space between the closing angle brackets > >
or is will be interpreted as >> which is the extraction
operator or right shift operator in bit manipulation. */