#include <bsl_list.h>
#include <bsl_deque.h>
stl::lower_bound
on set is not a good choice. It assume the
container is sequential, use member function version, the same case for erase
etc.The only real difference, structurally, between a set and a map is the type of the container element.
A set<T>
is (usually) implemented as a red-black tree whose nodes contain a const T. (A tree node probably contains three pointers and a byte that indicates whether the node is red or black.)
A map<K ,T>
is implemented in exactly the same way (and probably uses the same code), but the tree node contains a pair<const K, T>.
Like set and multiset, map and multimap automatically sort their elements according to a sorting criterion but only used on keys
typedef
of map is strongly preferred, because it is vert long.
#include <bsl_map.h>
#include <bsl_string.h>
#include <cusip.h>
typedef bsl::map<bsl::string, Cusip> Securities;
typedef Securities::iterator I;
typedef Securities::const_iterator CI;
typedef Securities::value_type VT; // important!
typedef Securities::size_type ST; // less important
typedef bsl::pair<I, bool> InsertRet;
Like set, a map insertion returns an iterator-bool pair first is an iterator to the element in the map second is a bool that tells you if the insertion took place
Indexing can be used for inserting, but NEVER USE FOR LOOKUP!
typedef
to hide your implementation so that you can modify it later.vector<Security>::iterator
list<Cusip>::const_iterator
bsl::vector<Security> sv;
typedef bsl::vector<Security>::const_iterator CI;
for (CI i = sv.begin(); i != sv.end(); ++i) {
bsl::cout << *i << '\n';
}
There are five categories of iterators:
all capabilities of bidirectional iterators
can also move many steps (in either direction) in constant time
Random access iterators: vector, deque, array
Bidirectional iterators: list, map, set
Forward iterators: unordered_set, unordered_map, forward_list
Input/output iterators: iostream iterators
extern double readings[];
extern list<double> seq;
copy(readings, readings+n,
seq.begin()); // overwrite!
copy(readings, readings+n,
back_inserter(seq)); // append
copy(readings, readings+n,
front_inserter(seq)); // prepend in reverse order
typedef vector<int> Cont;
typedef Cont::iterator I;
typedef Cont::reverse_iterator RI;
Cont v;
...
sort(v.begin(), v.end()); // sort in order
sort(v.rbegin(), v.rend()); // sort in reverse order
I i = find(v.begin(), v.end(), 3); // find first 3
RI r = find(v.rbegin(), v.rend(), 3); // find last 3
list<Cusip> c1;
...
vector<Cusip> c2;
// copy c1 to c2, version 1
typedef list<Cusip>::iterator I;
for (I i = c1.begin(); i != c1.end(); ++i)
c2.push_back(*i); // low-tech, gauche
// copy c1 to c2, version 2
copy(c1.begin(), c1.end(), c2.begin()); // error!
// copy c1 to c2, version 3
copy(c1.begin(), c1.end(),
back_inserter(c2)); // works!
// copy c1 to c2, version 4
vector<Cusip> c2(c1.begin(), c1.end()); // best way
#include <bsl_algorithm.h>
#include <bsl_iostream.h>
#include <bsl_algorithm.h>
#include <bsl_cstring.h>
void main() {
const char *s = "IBM|76.89";
size_t len = strlen(s);
const char *p = find(s, s+len, '|');
if (p != s+len) {
bsl::cout << "Price: " << p+1 << '\n';
// prints Price: 76.89
}
}
#include <bsl_list.h>
#include <bsl_algorithm.h>
list<unsigned long> nums;
bool isRamanujan(unsigned long);
...
list<unsigned long>::const_iterator i =
find_if(nums.begin(), nums.end(), isRamanujan);
if (i == nums.end()) {
// not found
} else {
// found
}
v.erase(remove(v.begin(), v.end(), 8), v.end());
v.erase(remove_if(v.begin(), v.end(), isPrime),
v.end());
DO NOT eraser remove on a container of poiner 因为remove之后保存在后面的内容是undefined,有可能误删掉valid的内容,同时应该被删的内容有可能会 leak
SOLUTION: use unique_ptr
or use partition
instead of erase
.
struct Score {
string name;
long score;
};
bool scoreComp(const Score &a, const Score &b) {
return (a.score > b.score)
? true : (b.score > a.score)
? false : a.name < b.name;
}
Score *scores;
size_t numScores = 0;
...
sort(scores, scores+numScores, scoreComp);
stable_sort
Equivalence means neither one is less than the other. Equality means one is equal to the other.
lower_bound
returns the head of the equivalent sequence.upper_bound
returns one past the tail of the equivalent sequence.greater<T>
, is a binary function, we sometimes want to use it as unary, we can
use bind1st, bind2nd
to make it unary.