䊐 Insertion MethodsThe following methods are defined in the container classes vector,deque,andlist ■ insert insert after a given position.. 䊐 The front and back MethodsAccess to individu
Trang 1䊐 Insertion Methods
The following methods are defined in the container classes vector,deque,andlist
■ insert() insert after a given position
Additionally, the following method is available in the listanddequeclasses
■ push_front() insert at beginning
This method is not defined in the vectorclass
Theinsert()method is overloaded in various versions, allowing you to insert a sin-gle object, multiple copies of an object, or object copies from another container Given two containers vandwthe following
Example: w.insert( w.begin(), v.begin(), v.end());
inserts the objects from container vin front of all the other objects in w A container can
of course be assigned to another container of the same type The assignment operator is overloaded for containers to allow this operation
䊐 Runtime Behavior
The push_back() andpush_front() methods are preferable on account of their
constant runtime Insertion of one object with the insert()method also has a con-stant runtime in the list class However, this is linear in the vector and deque
classes, that is, the time increases proportionally to the number of objects in the con-tainer
This dissimilar runtime behavior for methods can be ascribed to the implementation
of various container classes Normally, containers of the list type are represented by double linked lists in which each element possesses a pointer to the preceding and fol-lowing element This allows for extremely quick inserting at a given position
The container classes vectoranddequeare represented as arrays Inserting in the middle means shifting the objects in the container to make place for the new object Therefore the runtime will increase proportionally with the number of objects the con-tainer holds
䊐 Insertion in Adapter Classes
There is only one insertion method for adapter classes: push() In stacks and queues,
push() appends an object with a constant runtime Insertion of objects into priority queues depends on the priority of the object and the runtime is linear
Trang 2760 C H A P T E R 3 3 C O N T A I N E R S
// sortvec.h
// using the binary search algorithms:
// "middle" element, it must belong to the left half or // else to the right half of the vector We repeat this // process comparing obj with the "middle" element in // the section where it is known to be, repeatedly // halving the size of the interval until the interval // consists of a single point, which is where obj // belongs
// This algorithm has logarithmic time and thus // is very fast
// -template <class T, class Compare >
int SortVec<T, Compare>::search(const T& obj) {
int first = 0, last = end() - begin() - 1, mid;
while( first < last ) {
mid = (first + last + 1)/ 2;
// Search the left half, if( obj < (*this)[mid] )
last = mid - 1;
else first = mid; // the right half
}
if ( obj == (*this)[first] ) // Found?
return first; // Yes
else return size(); // Not found
}
Method search() of container class sortVec
Trang 3䊐 The front() and back() Methods
Access to individual objects in the container classes vector,deque, and listcan be performed by the following methods
■ front() for access to the first element and
■ back() for access to the last element
Both methods return a reference to the object in question
Example: double z = v.front();
v.front() = 1.9;
This saves the first object in container vin the variable zand then overwrites the object
by1.9
䊐 Access via Indices
The subscript operator []is overloaded in the vectoranddequeclasses to permit the use of indices for access to the objects in a container An index is a positive integer of the type size_type
Example: v[20] = 11.2; // the 21st object
Given that posis an iterator that references the first object in a container v, the expres-sionv[20]is equivalent to pos[20]
When you use the subscript operator, you must ensure that the index does not exceed the valid range You can use the access method at()to throw an exception if an index
is out of range
Example: v.at(20) = 11.2;
Theat()method throws an exception of the standard error class out_of_rangeif an error occurs
The subscript operator and the at() method are not defined in the list class Before you can manipulate the tenth object in the container, for example, you need to walk through the container sequentially up to that position
䊐 Access to Objects in Adapter Classes
The method top()is defined for access to the element with the highest priority, or the element at the top of the stack, in the adapter classes priority_queueandstack The queueclass comprises the front() method, which is used to access the first element
Trang 4762 C H A P T E R 3 3 C O N T A I N E R S
// sortvec.h: Method merge() merges the argument vector // with the vector *this
// -template <class T, class Compare >
void SortVec<T,Compare>::merge(const SortVec<T,
Compare>& v) {
SortVec temp; // Temporary vector SortVec::iterator pos = begin(); // Iterator
int n1 = 0, n2 = 0;
// Copy the smaller object into vector temp: while(n1 < size() && n2 < v.size())
if( pos[n1] <= v[n2] ) temp.push_back(pos[n1++]);
else temp.push_back(v[n2++]);
// Append the rest: while( n1 < size())
temp.push_back(pos[n1++]);
while( n2 < v.size()) temp.push_back(v[n2++]);
*this = temp;
}
Method merge() of container class SortVec
Trang 5The identifying features of a container are
■ its length, that is, the number of objects held in the container, and
■ the capacity, that is, the maximum number of objects the container can store.
The length of a container changes after every insertion or deletion—the capacity does not
䊐 Length of a Container
The length of a container is discovered by a call to the size()method The method returns an integer of the size_typetype
Example: Fraction x(1, 1);
vector<Fraction> v(100, x);
vector<Fraction>::size_type sz = v.size();
The variable szcontains the value 100in this case
The length of an empty container is always 0 You can also use the empty()method
to discover whether a container is empty The method returns truein this case
Example: while( !cont.empty() )
The methods size()andempty()are defined for all container classes You can use theresize()method to change the length of a container
Example: cont.resize( n, x);
The length is increased to n provided n > size() is true, or decreased for n < size() If n == size(), nothing happens
If the length is increased, n – size()copies of the object xare appended to the container The second argument, x, can be omitted In this case, the default constructor for a type Tobject is called as often as necessary
䊐 Capacity
The capacity of a container can be checked using the max_size()method
Example: size_type k = cont.max_size();
The return value depends on the amount of memory available and the object size Only the size()andempty()methods are defined for adapter classes You cannot discover the capacity of an object, nor can you call resize()to change its length
Trang 6764 C H A P T E R 3 3 C O N T A I N E R S
// prior_t.cpp : Testing a priority queue //
-#include <queue>
#include <string>
#include <iostream>
using namespace std;
class Parcel {
private:
unsigned int prio; // Priority string info;
public:
Parcel(unsigned int p, const string& s)
:prio(p), info(s) {} // Access methods, overloaded operators:
friend bool operator<(const Parcel& x,const Parcel& y)
{ return (x.prio < y.prio); } friend ostream& operator<<(ostream& os,
const Parcel& x) { os << x.prio << " "<< x.info << endl; return os; } };
int main() {
priority_queue<Parcel> pq;
pq.push(Parcel(7,"Bob")); // Insert pq.push(Parcel(1,"Peter"));
pq.push(Parcel(4,"Susan"));
while( !pq.empty() ) {
cout << pq.top() << endl; // Output
} return 0;
} // Output: 7 Bob // 4 Susan // 1 Peter
A priority queue
Trang 7䊐 Deletion Methods
The following methods are available for deleting objects in the container classes vec-tor,deque, and list:
■ pop_back() deletes the last object in the container
■ erase() deletes the object at a given position, or deletes all the objects in
a given range
■ clear() deletes all the objects in a container
The following method is additionally defined in the dequeandlistclasses:
■ pop_front() deletes the first object in the container
The method does not have a return value, just like the pop_back()method
The pop_back() and pop_front() methods are preferable on account of their constant runtimes Using the erase()method to delete an object at the beginning or
in the middle of a container also provides a constant runtime in the container class
list However, the runtime is linear in the vectoranddequeclasses, since objects must be shifted within the container to fill the gap left by the deletion
䊐 Deleting Ranges of Objects
When you use the erase()method to delete the objects in a given range, the position
of the first element to be deleted and the position after the last object to be deleted are
required as arguments
Example: cont.erase(cont.begin() + 10, cont.end());
This deletes all the remaining objects in the container, starting at position 11 The
erase()method returns the new position of the object immediately after the range of objects deleted
䊐 Deletion in Adapter Classes
There is only one method of deletion for adapter classes, namely pop() Given that
waitis a queue of the queuetype, the following statement
Example: wait.pop();
deletes the element at the beginning of the queue In the case of a stack, pop()deletes the element at the top of the stack, and for priority queues, the object with the highest priority The runtime is constant in all cases
Trang 8766 C H A P T E R 3 3 C O N T A I N E R S
// list_t.cpp: Tests list operations //
-#include <list>
#include <cstdlib>
#include <iostream>
using namespace std;
typedef list<int> INTLIST;
int display( const INTLIST& c);
int main() {
INTLIST ls, sls;
int i;
for( i = 1; i <= 3; i++) ls.push_back( rand()%10 ); // ex 1 7 4
ls.push_back(ls.front()); // 1 7 4 1
ls.reverse(); // 1 4 7 1
ls.sort(); // 1 1 4 7
for( i = 1; i <= 3; i++) sls.push_back( rand()%10 ); // ex 0 9 4
// Insert first object of sls before the last in ls: INTLIST::iterator pos = ls.end();
ls.splice( pos, sls, sls.begin()); // 1 1 4 0 7
display(sls); // 9 4
ls.sort(); // 0 1 1 4 7 sls.sort(); // 4 9
ls.merge(sls); // 0 1 1 4 4 7 9 ls.unique(); // 0 1 4 7 9
return 0;
}
Sample program
Trang 9The container class listcomprises methods for list operations that are not defined in other container classes These are
■ sorting and inverting lists
■ merging two sorted lists
■ splicing lists
䊐 Sorting, Inverting, and Splicing Lists
A container of the list type, or list container for short, can be sorted by a call to
sort() This assumes that the operator <is defined in class T A call to sort()sorts the container in ascending order
You can use the reverse()method to invert a list container, that is, to reverse the order of the objects in the container What was originally the first element in the con-tainer becomes the last, and the second element becomes the second to last, and so on Themerge()method is used to merge two list containers Given that ls1andls2
are two sorted list containers, the following call
Example: ls1.merge(ls2);
creates the sorted list ls1, whose objects comprise the original objects of ls1andls2 Thels2container is empty following this operation
䊐 Splice Operations
Splice operations insert the objects from one list container at a given position in another
list container and remove them from the original container You can transfer either a whole container or just part of a container
Example: ls1.splice(pos, ls2);
This inserts the whole of container ls2in front of positionposinls1.ls2is emptied
by this statement The following statement
Example: ls1.splice(pos1, ls2, pos2);
Inserts the element at position pos2inls2before the element at position pos1inls1
and deletes it from ls2 If you want to transfer part of a container, the third and fourth arguments must contain the starting and end position
You cannot use a splice operation to insert at a position before begin() or after
end()
Trang 10768 C H A P T E R 3 3 C O N T A I N E R S
Container Class Representing
set< class T, class Compare = less<T>, class Allocator = allocator<T> >
collections of objects with unique keys
multiset< class T, class Compare = less<T>, class Allocator = allocator<T> >
collections of objects with equivalent keys, i.e possibly multiple copies of the same key value
map< class Key, class T, class Compare = less<T>, class Allocator = allocator<T> >
collections of objects/key pairs where the keys are unique
multimap< class Key, class T, class Compare = less<T>, class Allocator = allocator<T> >
collections of objects/key pairs with possibly equivalent keys
Container Class Header File
set< T, Compare, Allocator >
multiset<T, Compare, Allocator >
map< Key, T, Compare, Allocator >
multimap< Key, T, Compare, Allocator >
<set>
<set>
<map>
<map>
Container classes
Associative containers and header files