An Introduction to Part of C++ STL
-
Upload
- -
Category
Technology
-
view
1.147 -
download
1
description
Transcript of An Introduction to Part of C++ STL
AN INTRODUCTION TO PART OF C++ STL
abcdabcd987 @ 2012.03.13
An Introduction to Part of C++ STL
Propaedeutic
Part of STL Algorithm
Part of STL Container
Examples
Propaedeutic
Pointer
Point to an address in memory.
#include <iostream>
using namespace std;
int main ()
{
int firstvalue, secondvalue;
int * mypointer = NULL;
mypointer = &firstvalue;
*mypointer = 10;
mypointer = &secondvalue;
*mypointer = 20;
cout << "firstvalue is " << firstvalue << endl;
cout << "secondvalue is " << secondvalue << endl;
return 0;
}
Const?? Pointer??
Able to change p && *p:
int* p;
Able to change p, but not *p
int* const p;
Able to change *p, but not p
const int* p;
Unable to change p || *p
const int* const p;
Array && operator[]
The name of an array is a pointer to the first
element of the array.
arr[index] equals to *(arr+index)
arr[0] equals to *arr
const int arr[] = {1, 2, 3, 4};
cout << arr[0] << endl
<< *arr << endl;
They are equal.
Reference
Similar to pointer, but not changeable.
int a = 0, b = 1;
int &ref = a;
ref = 2;
Using in function parameter:
#include <iostream>
using namespace std;
int sum(int (&a)[4])
{
return a[0]+a[1]+a[2]+a[3];
}
int main()
{
int arr[4] = {1, 2, 3, 4};
cout << sum(arr);
}
Dynamic Memory
pointer = new type;
pointer = new type [number_of_elements];
delete pointer;
delete [] pointer;
int *pa = new int;
int *parr = new int[10];
*pa = 1, parr[0] = 1;
delete pa;
delete [] pa;
Templates
template<typename T>
inline const T& max(const T& a, const T& b)
{
return a > b ? a : b;
}
template<typename T1, typename T2>
struct pair
{
T1 first;
T2 second;
};
template<typename T, size_t N>
class array
{
T _data[N];
};
Overloaded Relational Operations
Non-member functions
operator==
operator<
#include <cmath>
class Float
{
const static double EPS = 1e-8;
double _data;
Float(const double x): _data(x) { }
friend bool operator==(const Float&, const Float&);
friend bool operator<(const Float&, const Float&);
};
inline bool operator==(const Float& lhs, const Float& rhs)
{ return std::abs(rhs._data-lhs._data) < Float::EPS; }
inline bool operator<(const Float& lhs, const Float& rhs)
{ return rhs._data-lhs._data > Float::EPS; }
pair
template <class T1, class T2> struct pair
{
typedef T1 first_type;
typedef T2 second_type;
T1 first;
T2 second;
pair() : first(T1()), second(T2()) {}
pair(const T1& x, const T2& y) : first(x), second(y) {}
template <class U, class V>
pair (const pair<U,V> &p) : first(p.first), second(p.second) { }
}
make_pair
template <class T1,class T2>
pair<T1,T2> make_pair (T1 x, T2 y)
{
return ( pair<T1,T2>(x,y) );
}
Notices: #include <algorithm>
using namespace std;
* Know it
$ Useful
! Extremely useful && important
Part of STL Algorithm
* std::equal - O(n)
template <class InputIterator1, class InputIterator2>
bool equal ( InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2 );
Compares the elements in the range
[first1,last1) with those in the range
beginning at first2, and returns true if the
elements in both ranges are considered equal.
int myints[] = {20,40,60,80,100};
int myints2[] = {20,40,60,80,100};
if (equal (mynts, myints+5, myints2))
cout << "The contents of both sequences are equal." << endl;
else
cout << "The contents of both sequences differ." << endl;
* std::fill - O(n)
template < class ForwardIterator, class T >
void fill ( ForwardIterator first, ForwardIterator last, const T& value );
Sets value to all elements in the range
[first,last).
vector<int> myvector (8); // myvector:00000000
fill (myvector.begin(),myvector.begin()+4,5);// myvector:55550000
fill (myvector.begin()+3,myvector.end()-2,8);// myvector:55588800
* std::find - O(n)
template <class InputIterator, class T>
InputIterator find ( InputIterator first, InputIterator last, const T&
value );
Returns an iterator to the first element in
the range [first,last) that compares equal to
value, or last if not found.
int myints[] = { 10, 20, 30 ,40 };
int * p = find(myints,myints+4,30);
++p;
cout << "The element following 30 is " << *p << endl;
$ std::lower_bound / std::upper_bound - O(logn) template <class ForwardIterator, class T>
ForwardIterator lower_bound ( ForwardIterator first, ForwardIterator
last, const T& value );
Returns an iterator pointing to the first
element in the sorted range [first,last) which
does not compare less than value.
int myints[] = {10,20,30,30,20,10,10,20};
vector<int> v(myints,myints+8); // 10 20 30 30 20 10 10 20
vector<int>::iterator low,up;
sort (v.begin(), v.end()); // 10 10 10 20 20 20 30 30
low=lower_bound (v.begin(), v.end(), 20); // ^
up= upper_bound (v.begin(), v.end(), 20); // ^
cout << "lower_bound at position " << int(low- v.begin()) << endl;
cout << "upper_bound at position " << int(up - v.begin()) << endl;
$ std::make_heap - O(n)
template <class RandomAccessIterator>
void make_heap ( RandomAccessIterator first, RandomAccessIterator last );
Rearranges the elements in the range [first,last) in such a way that they form a heap.
#include <funcional>
int myints[] = {10,20,30,5,15};
make_heap (myints,myints+5);
cout << "initial max heap : " << myints[0] << endl;
make_heap (myints,myints+5,greater<int>());
cout << "initial min heap : " << myints[0] << endl;
$ std::push_heap / std::pop_heap - O(logn)
template <class RandomAccessIterator>
void push_heap ( RandomAccessIterator first, RandomAccessIterator last );
template <class RandomAccessIterator>
void pop_heap ( RandomAccessIterator first, RandomAccessIterator last );
$ std::sort_heap - O(nlogn)
template <class RandomAccessIterator>
void sort_heap ( RandomAccessIterator first, RandomAccessIterator last );
Rearranges the elements in the heap range
[first,last) in such a way that they form a
sorted range.
The range loses its heap properties.
int myints[] = {10,20,30,5,15};
make_heap (myints,myints+5)
cout << "initial max heap : " << v.front() << endl;
sort_heap (myints,myints+5;
cout << "final sorted range :";
for (unsigned i=0; i<5; i++) cout << " " << myints[i];
$ std::max_element / std::min_element - O(n) template <class ForwardIterator>
ForwardIterator max_element ( ForwardIterator first, ForwardIterator
last );
Returns an iterator pointing to the
element with the largest value in the
range [first,last).
int myints[] = {3,7,2,5,6,4,9};
cout << "The smallest element is " << *min_element(myints,myints+7) <<
endl;
cout << "The largest element is " << *max_element(myints,myints+7) << endl;
$ std::nth_element - On average O(n)
template <class RandomAccessIterator>
void nth_element ( RandomAccessIterator first, RandomAccessIterator nth,
RandomAccessIterator last );
Rearranges the elements in the range
[first,last), in such a way that the element at
the resulting nth position is the element that
would be in that position in a sorted sequence,
with none of the elements preceding it being
greater and none of the elements following it
smaller than it.
Neither the elements preceding it nor the
elements following it are guaranteed to be
ordered.
! std::swap - O(1)
template <class T> void swap ( T& a, T& b )
{
T c(a); a=b; b=c;
}
! std::max / std::min - O(1)
template <class T> const T& max ( const T& a, const T& b ) {
return (a<b)?b:a;
}
! std::sort - O(nlogn)
template <class RandomAccessIterator>
void sort ( RandomAccessIterator first, RandomAccessIterator last );
int myints[] = {32,71,12,45,26,80,53,33};
sort (myints, myints+8);
! std::sort - O(nlogn)
Sort by two keys:
#include <iostream>
#include <algorithm>
struct Point
{
int x, y;
Point(const int _x = 0, const int _y = 0): x(_x), y(_y) { }
};
inline bool operator<(const Point& lhs, const Point& rhs)
{ return lhs.x < rhs.x || (lhs.x == rhs.x && lhs.y < rhs.y); }
! std::sort - O(nlogn)
Point a[100];
int n;
int main()
{
std::cin >> n;
for (int i = 0; i < n; ++i)
std::cin >> a[i].x >> a[i].y;
std::sort(a, a+n);
std::cout << std::endl;
for (int i = 0; i < n; ++i)
std::cout << a[i].x << ' ' << a[i].y << std::endl;
std::cout << std::endl << (a[1] < a[2])
<< std::endl << (a[2] < a[1]);
}
! std::unique - O(n)
template <class ForwardIterator>
ForwardIterator unique ( ForwardIterator first, ForwardIterator last );
Removes the duplicate consecutive elements
from the range [first,last). This is done by
removing from the resulting range all the
elements that compare equal to the element
right preceding them (only the first element in
each group of consecutive equal elements is
kept).
The resulting range consists of the elements
between first and the iterator returned by the
function, which points to the new end of range.
The elements past the new end of range are
still valid, although with unspecified values.
int myints[] = {10,20,20,20,30,30,20,20,10};
sort(myints, myints+9);
int n = unique(myints, myints+9) - myints;
! vector
! deque
list
! stack
! queue
priority_queue
! set
multiset
! map
multimap
! bitset
A Part of STL Container
vector deque set map bitset
begin O(1) v v v v
end O(1) v v v v
rbegin O(1) v v v v
rend O(1) v v v v
size * O(1) O(1) O(1) O(1) O(1)
empty O(1) v v v v v
front O(1) v v v
back O(1) v v v
operator[] * O(1) O(1) O(logn) O(logn) O(1)
at O(1) v v
assign O(n) v v
insert * O(n) O(n) O(logn) O(logn)
erase * O(n) O(n) O(logn) O(logn)
clear O(n) v v v v
push_front O(1) v v
pop_front O(1) v v
push_back O(1) v v v
pop_back O(1) v v v
find O(logn) v v
count O(logn) v v v
Initializing Container Elements
C<T> c; Create an empty container named c . C is a container
name, such as vector , and T is the element type.
C c(c2); Create c as a copy of container c2 ; c and c2 must be
the same container type and hold values of the same
type.
C c(b, e); Create c with a copy of the elements from the range
denoted by iterators b and e .
C c(n, t); Create c with n elements, each with value t , which
must be a value of the element type of C or a type
convertible to that type.
Sequential containers only.
C c(n); Create c with n value-initialized
Sequential containers only.
Iterators
*iter
iter->mem
++iter iter++
--iter iter--
iter1 == iter2
iter2 != iter2
Operations Supported by vector and deque
Iterators:
iter+n iter-n
iter1 += iter2 iter1 -= iter2
iter1 - iter2
> >= < <=
Iterator Ranges && Container-Defined Iterator Typedefs
[ first, last )
while (first != last) {
// safe to use *first because we know there is at least one element
++first;
}
iterator Type of the iterator for this container
type
const_iterator Type of the iterator that can read but
not write the elements
reverse_iterator Iterator that addresses elements in
reverse order
const_reverse_iterator Reverse iterator that can read but not
write the elements
begin and end Members
for (vector<int>::reverse_iterator beg = c.rbegin(); beg != c.rend();
++beg)
{
}
c.begin() Yields an iterator referring to the first element in
c
c.end() Yields an iterator referring to the one past the
last element in c
c.rbegin() Yields a reverse iterator referring to the last
element in c
c.rend() Yields a reverse iterator referring one past (i.e.,
before) the first element in c
Operations that Add Elements to a Sequential Container
c.push_back(t) Adds element with value t to the end of c .
Returns void .
c.push_front(t) Adds element with value t to front of c . Returns
void .
Valid only for list or deque .
c.insert(p,t) Inserts element with value t before the element
referred to by iterator p . Returns an iterator
referring to the element that was added.
c.insert(p,n,t) Inserts n elements with value t before the
element referred to by iterator p . Returns void .
c.insert(p,b,e) Inserts elements in the range denoted by
iterators b and e before the element referred to
by iterator p . Returns void .
Size Operations && Access Elements
c.size() Returns the number of elements in c . Return type
is c::size_type .
c.empty() Returns a bool that indicates whether size is 0 or
not.
c.back() Returns a reference to the last element in c .
Undefined if c is empty.
c.front() Returns a reference to the first element in c .
Undefined if c is empty.
c[n] Returns a reference to the element indexed by n .
Undefined if n <0 or n >= c.size() .
Valid only for vector and deque .
c.at(n) Returns a reference to the element indexed by n .
If index is out of range, throws out_of_range
exception.
Valid only for vector and deque .
Operations to Remove Elements
c.erase(p) Removes element referred to by the iterator p .
Returns an iterator referring to the element after
the one deleted, or an off-the-end iterator if p
referred to the last element. Undefined if p is an
off-the-end iterator.
c.erase(b,e) Removes the range of elements denoted by the
iterators b and e . Returns an iterator referring
after the last one in the range that was deleted,
or an off-the-end iterator if e is itself an off-
the-end iterator.
c.clear() Removes all the elements in c . Returns void .
c.pop_back() Removes the last element in c . Returns void .
Undefined if c is empty.
c.pop_front() Removes the first element in c . Returns void .
Undefined if c is empty.
Valid only for list or deque .
stack
stack<T> s;
bool empty ( ) const;
void pop ( );
void push ( const T& x );
size_type size ( ) const;
value_type& top ( );
const value_type& top ( ) const;
queue
queue<T> q;
value_type& back ( );
const value_type& back ( ) const;
bool empty ( ) const;
value_type& front ( );
const value_type& front ( ) const;
void pop ( );
void push ( const T& x );
size_type size ( ) const;
deque
deque<T> d;
reference at ( size_type n );
const_reference at ( size_type n ) const;
reference operator[] ( size_type n );
const_reference operator[] ( size_type n ) const;
bool empty ( ) const;
reference front ( );
const_reference front ( ) const;
void pop_back ( );
void pop_front ( );
void push_back ( const T& x );
void push_front ( const T& x );
priority_queue
priority_queue<T> p;
priority_queue<T, vector<T>, greater<T> > p;
value_type& back ( );
const value_type& back ( ) const;
bool empty ( ) const;
value_type& front ( );
const value_type& front ( ) const;
void pop ( );
void push ( const T& x );
size_type size ( ) const;
vector
vector<T> v;
reference back ( );
const_reference back ( ) const;
reference front ( );
const_reference front ( ) const;
reference operator[] ( size_type n );
const_reference operator[] ( size_type n ) const;
void pop_back ( );
void push_back ( const T& x );
size_type size() const;
bitset
bitset<N> s;
bool any ( ) const;
size_t count ( );
bitset<N>& flip ( );
bitset<N>& flip ( size_t pos );
bool none ( ) const;
reference operator[] ( size_t pos );
bool operator[] ( size_t pos ) const;
bitset<N>& set ( size_t pos, bool val = true );
bool test ( size_t pos ) const;
template <class charT, class traits, class Allocator>
basic_string<charT,traits,Allocator> to_string() const;
unsigned long to_ulong ( ) const;
map
map<Key, T> m;
map<string, int> m;
bool empty ( ) const;
void erase ( iterator position ); // O(1)
size_type erase ( const key_type& x ); // O(logn)
iterator find ( const key_type& x );
const_iterator find ( const key_type& x ) const;
pair<iterator,bool> insert ( const value_type& x );
T& operator[] ( const key_type& x );
If x does not match the key of any element in the
container, the function inserts a new element with
that key and returns a reference to its mapped value.
set
set<T> s;
size_type count ( const key_type& x ) const;
bool empty ( ) const;
void erase ( iterator position ); // O(1)
size_type erase ( const key_type& x ); // O(logn)
iterator find ( const key_type& x ) const;
pair<iterator,bool> insert ( const value_type& x );
Examples
USACO - majesty
#include <cstdio>
#include <algorithm>
struct pair
{
unsigned int x, y;
} a[100000];
inline bool operator<(const pair& lhs, const pair& rhs)
{ return lhs.x < rhs.x || (lhs.x == rhs.x && lhs.y < rhs.y); }
inline bool operator==(const pair& lhs, const pair& rhs)
{ return lhs.x <= rhs.x && rhs.y <= lhs.y; }
inline unsigned int sqr(const unsigned int x) { return x*x; }
int n;
USACO - majesty
int main()
{
scanf("%d", &n);
for (int i = 0; i < n; ++i)
scanf("%d%d", &a[i].x, &a[i].y);
std::sort(a, a+n);
n = std::unique(a, a+n) - a;
unsigned int area(sqr(a[0].y-a[0].x));
for (int i = 1; i < n; ++i)
{
area += sqr(a[i].y-a[i].x);
if (a[i].x < a[i-1].y)
area -= sqr(a[i-1].y-a[i].x);
}
printf("%d", area);
}
pku3668
#include <cstdio>
#include <set>
const double EPS(1e-8), INF(5.14376922e10);
int n, a[200][2];
struct Float
{
double data;
Float(const double& x): data(x) { }
};
inline bool operator<(const Float& lhs, const Float& rhs)
{ return rhs.data-lhs.data > EPS; }
std::set<Float> lines;
pku3668
int main()
{
scanf("%d", &n);
for (int i = 0; i < n; ++i)
scanf("%d%d", &a[i][0], &a[i][1]);
for (int i = 0; i < n; ++i)
for (int j = i+1; j < n; ++j)
{
const int dx = a[i][0]-a[j][0], dy = a[i][1]-a[j][1];
const Float slope(dy == 0 ? INF : static_cast<double>(dx)/dy);
lines.insert(slope);
}
printf("%d", static_cast<int>(lines.size()));
}
pku3669
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
const int xy[5][2] = {{0, -1}, {0, 1}, {-1, 0}, {1, 0}, {0, 0}};
struct Info
{
int x, y, step;
Info(const int _x = 0, const int _y = 0, const int _s = 0): x(_x), y(_y),
step(_s) { }
};
int n, time[401][401], vis[401][401];
int main()
{
//略
pku3669
std::queue<Info> q;
if (time[0][0] != 0)
{
q.push(Info(0, 0, 0));
vis[0][0] = 0;
}
for (; !q.empty(); q.pop())
for (int i = 0; i < 4; ++i)
{
const int xx = q.front().x+xy[i][0], yy = q.front().y+xy[i][1], step = q.front().step+1;
if (xx < 0 || yy < 0 || time[xx][yy] <= step || vis[xx][yy] >= step)
continue;
if (time[xx][yy] == 0x3F3F3F3F)
{
printf("%d", step);
return 0;
}
vis[xx][yy] = step;
q.push(Info(xx, yy, step));
}
printf("-1");
}
pku2823
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
int n, k;
vector<int> a;
deque<int> Qmin, Qmax;
int main()
{
ios::sync_with_stdio(false);
cin >> n >> k;
for (int i = 0, x; i != n; ++i)
{
cin >> x;
a.push_back(x);
}
pku2823
for (int i = 0; i != k-1; ++i)
{
while (!Qmin.empty() && a[Qmin.back()] >= a[i]) Qmin.pop_back();
while (!Qmax.empty() && a[Qmax.back()] <= a[i]) Qmax.pop_back();
Qmin.push_back(i);
Qmax.push_back(i);
}
for (int i = k-1; i != n; ++i)
{
while (!Qmin.empty() && Qmin.front() <= i-k) Qmin.pop_front();
while (!Qmin.empty() && a[Qmin.back()] >= a[i]) Qmin.pop_back();
Qmin.push_back(i);
cout << a[Qmin.front()] << ' ';
}
//略
}
bzoj1724
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int n;
vector<int> a;
int main() {
ios::sync_with_stdio(false);
cin >> n;
for (int i = 0, x; i < n; ++i) {
cin >> x;
a.push_back(x);
}
bzoj1724
make_heap(a.begin(), a.end(), greater<int>());
long long result = 0;
for (int i = 1; i < n; ++i) {
int tmp = a.front();
pop_heap(a.begin(), a.end(), greater<int>());
a.pop_back();
tmp += a.front();
pop_heap(a.begin(), a.end(), greater<int>());
a.pop_back();
a.push_back(tmp);
push_heap(a.begin(), a.end(), greater<int>());
result += tmp;
}
cout << result;
}
http://www.cplusplus.com/
http://www.sgi.com/tech/stl/
References
THE END
Thanks